diff --git a/browser_patches/export.sh b/browser_patches/export.sh index 4148009eb8..2652a21551 100755 --- a/browser_patches/export.sh +++ b/browser_patches/export.sh @@ -41,13 +41,13 @@ EXPORT_PATH="" if [[ ("$1" == "firefox") || ("$1" == "firefox/") || ("$1" == "ff") ]]; then FRIENDLY_CHECKOUT_PATH="//browser_patches/firefox/checkout"; CHECKOUT_PATH="$PWD/firefox/checkout" - EXPORT_PATH="$PWD/firefox/" + EXPORT_PATH="$PWD/firefox" BUILD_NUMBER_UPSTREAM_URL="https://raw.githubusercontent.com/microsoft/playwright/master/browser_patches/firefox/BUILD_NUMBER" source "./firefox/UPSTREAM_CONFIG.sh" elif [[ ("$1" == "webkit") || ("$1" == "webkit/") || ("$1" == "wk") ]]; then FRIENDLY_CHECKOUT_PATH="//browser_patches/webkit/checkout"; CHECKOUT_PATH="$PWD/webkit/checkout" - EXPORT_PATH="$PWD/webkit/" + EXPORT_PATH="$PWD/webkit" BUILD_NUMBER_UPSTREAM_URL="https://raw.githubusercontent.com/microsoft/playwright/master/browser_patches/webkit/BUILD_NUMBER" source "./webkit/UPSTREAM_CONFIG.sh" else @@ -112,14 +112,11 @@ fi CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) NEW_BASE_REVISION=$(git merge-base $REMOTE_BROWSER_UPSTREAM/$BASE_BRANCH $CURRENT_BRANCH) -NEW_DIFF=$(git diff --diff-algorithm=myers --full-index $NEW_BASE_REVISION $CURRENT_BRANCH) +NEW_DIFF=$(git diff --diff-algorithm=myers --full-index $NEW_BASE_REVISION $CURRENT_BRANCH -- . ":!Tools/Playwright") + # Increment BUILD_NUMBER BUILD_NUMBER=$(curl ${BUILD_NUMBER_UPSTREAM_URL}) BUILD_NUMBER=$((BUILD_NUMBER+1)) -if [[ "$NEW_BASE_REVISION" == "$BASE_REVISION" && "$OLD_DIFF" == "$NEW_DIFF" ]]; then - echo "No changes" - exit 0 -fi echo "REMOTE_URL=\"$REMOTE_URL\" BASE_BRANCH=\"$BASE_BRANCH\" @@ -127,6 +124,13 @@ BASE_REVISION=\"$NEW_BASE_REVISION\"" > $EXPORT_PATH/UPSTREAM_CONFIG.sh echo "$NEW_DIFF" > $EXPORT_PATH/patches/$PATCH_NAME echo $BUILD_NUMBER > $EXPORT_PATH/BUILD_NUMBER +if [[ ("$1" == "webkit") || ("$1" == "webkit/") || ("$1" == "wk") ]]; then +echo "-- patching WebKit embedders" +rm -rf $EXPORT_PATH/src/* +mkdir $EXPORT_PATH/src/Tools +cp -r Tools/Playwright $EXPORT_PATH/src/Tools/ +fi + NEW_BASE_REVISION_TEXT="$NEW_BASE_REVISION (not changed)" if [[ "$NEW_BASE_REVISION" != "$BASE_REVISION" ]]; then NEW_BASE_REVISION_TEXT="$YEL$NEW_BASE_REVISION (changed)$END" diff --git a/browser_patches/prepare_checkout.sh b/browser_patches/prepare_checkout.sh index 68e150d773..cb5d43d432 100755 --- a/browser_patches/prepare_checkout.sh +++ b/browser_patches/prepare_checkout.sh @@ -31,6 +31,7 @@ FRIENDLY_CHECKOUT_PATH=""; CHECKOUT_PATH="" PATCHES_PATH="" BUILD_NUMBER="" +PLAYWRIGHT_PATH="" if [[ ("$1" == "firefox") || ("$1" == "firefox/") || ("$1" == "ff") ]]; then FRIENDLY_CHECKOUT_PATH="//browser_patches/firefox/checkout"; CHECKOUT_PATH="$PWD/firefox/checkout" @@ -41,6 +42,7 @@ elif [[ ("$1" == "webkit") || ("$1" == "webkit/") || ("$1" == "wk") ]]; then FRIENDLY_CHECKOUT_PATH="//browser_patches/webkit/checkout"; CHECKOUT_PATH="$PWD/webkit/checkout" PATCHES_PATH="$PWD/webkit/patches" + PLAYWRIGHT_PATH="$PWD/webkit/src/Tools/Playwright" BUILD_NUMBER=$(cat "$PWD/webkit/BUILD_NUMBER") source "./webkit/UPSTREAM_CONFIG.sh" else @@ -110,6 +112,13 @@ fi git checkout -b playwright-build echo "-- applying patches" git apply --index $PATCHES_PATH/* + +if [[ ("$1" == "webkit") || ("$1" == "webkit/") || ("$1" == "wk") ]]; then +echo "-- adding WebKit embedders" +cp -r $PLAYWRIGHT_PATH Tools +git add Tools/Playwright +fi + git commit -a --author="playwright-devops " -m "chore: bootstrap build #$BUILD_NUMBER" echo diff --git a/browser_patches/webkit/BUILD_NUMBER b/browser_patches/webkit/BUILD_NUMBER index f8d65c3166..b0536459d7 100644 --- a/browser_patches/webkit/BUILD_NUMBER +++ b/browser_patches/webkit/BUILD_NUMBER @@ -1 +1 @@ -1204 +1205 diff --git a/browser_patches/webkit/patches/bootstrap.diff b/browser_patches/webkit/patches/bootstrap.diff index da6858771a..b8afdc4cf0 100644 --- a/browser_patches/webkit/patches/bootstrap.diff +++ b/browser_patches/webkit/patches/bootstrap.diff @@ -13702,5454 +13702,6 @@ index 44301d5fef9c977dc0228b9de1ae75263efd9014..0c8c7e176a6e02ca04872cdd362d0a89 add_subdirectory(WebKitTestRunner) + add_subdirectory(Playwright/win) endif () -diff --git a/Tools/Playwright/Configurations/Base.xcconfig b/Tools/Playwright/Configurations/Base.xcconfig -new file mode 100644 -index 0000000000000000000000000000000000000000..fc61d5227c8608488514cbd92a28dc7c1c2efaf4 ---- /dev/null -+++ b/Tools/Playwright/Configurations/Base.xcconfig -@@ -0,0 +1,87 @@ -+// Copyright (C) 2010-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. ``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 -+// 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? "../../../../Internal/Configurations/HaveInternalSDK.xcconfig" -+#include "SDKVariant.xcconfig" -+ -+USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION)); -+USE_INTERNAL_SDK_Production = YES; -+USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK); -+USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK); -+ -+GCC_PREPROCESSOR_DEFINITIONS = DISABLE_LEGACY_WEBKIT_DEPRECATIONS $(inherited); -+ -+CLANG_CXX_LANGUAGE_STANDARD = gnu++1z; -+CLANG_CXX_LIBRARY = libc++; -+CLANG_ENABLE_OBJC_WEAK = YES; -+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; -+PREBINDING = NO -+GCC_C_LANGUAGE_STANDARD = gnu99 -+GCC_ENABLE_CPP_EXCEPTIONS = NO; -+GCC_PRECOMPILE_PREFIX_HEADER = YES -+ENABLE_STRICT_OBJC_MSGSEND = YES; -+GCC_TREAT_WARNINGS_AS_ERRORS = YES -+CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; -+CLANG_WARN_BOOL_CONVERSION = YES; -+CLANG_WARN_COMMA = YES; -+CLANG_WARN_CONSTANT_CONVERSION = YES; -+CLANG_WARN_EMPTY_BODY = YES; -+CLANG_WARN_ENUM_CONVERSION = YES; -+CLANG_WARN_INFINITE_RECURSION = YES; -+CLANG_WARN_INT_CONVERSION = YES; -+CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; -+CLANG_WARN_STRICT_PROTOTYPES = YES; -+CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; -+CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; -+CLANG_WARN_SUSPICIOUS_MOVE = YES; -+CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; -+CLANG_WARN_UNREACHABLE_CODE = YES; -+GCC_WARN_64_TO_32_BIT_CONVERSION = YES; -+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; -+GCC_WARN_ABOUT_RETURN_TYPE = YES; -+GCC_WARN_UNINITIALIZED_AUTOS = YES; -+GCC_WARN_UNUSED_FUNCTION = YES -+GCC_WARN_UNUSED_VARIABLE = YES -+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; -+GCC_WARN_UNDECLARED_SELECTOR = YES; -+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; -+CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; -+GCC_VERSION = com.apple.compilers.llvm.clang.1_0; -+WARNING_CFLAGS = -Wall -W -Wno-unused-parameter -+GCC_NO_COMMON_BLOCKS = YES; -+ -+SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx tvos tvsimulator watchos watchsimulator; -+ -+TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier)); -+TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300; -+TARGET_MAC_OS_X_VERSION_MAJOR_14 = 101400; -+TARGET_MAC_OS_X_VERSION_MAJOR_15 = 101500; -+TARGET_MAC_OS_X_VERSION_MAJOR_16 = 101600; -+ -+SDKROOT = macosx.internal; -+ -+OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS); -+OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS); -+OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS); -+ -+CODE_SIGN_IDENTITY = -; -diff --git a/Tools/Playwright/Configurations/DebugRelease.xcconfig b/Tools/Playwright/Configurations/DebugRelease.xcconfig -new file mode 100644 -index 0000000000000000000000000000000000000000..44dc1139c298bd119368ef4f45bbf0888dc71cdb ---- /dev/null -+++ b/Tools/Playwright/Configurations/DebugRelease.xcconfig -@@ -0,0 +1,45 @@ -+// Copyright (C) 2010, 2013 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. ``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 -+// 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 "Base.xcconfig" -+ -+ARCHS = $(ARCHS_STANDARD_32_64_BIT); -+ -+ONLY_ACTIVE_ARCH = YES; -+ -+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); -+ -+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR)) -+MACOSX_DEPLOYMENT_TARGET_101300 = 10.13; -+MACOSX_DEPLOYMENT_TARGET_101400 = 10.14; -+MACOSX_DEPLOYMENT_TARGET_101500 = 10.15; -+MACOSX_DEPLOYMENT_TARGET_101600 = 10.16; -+ -+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; -+ -+SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK)); -+SDKROOT_ = macosx; -+SDKROOT_YES = macosx.internal; -+ -+WK_CCACHE_DIR = $(SRCROOT)/../ccache; -+#include "../../ccache/ccache.xcconfig" -diff --git a/Tools/Playwright/Configurations/Playwright.xcconfig b/Tools/Playwright/Configurations/Playwright.xcconfig -new file mode 100644 -index 0000000000000000000000000000000000000000..d05c841a5b0f5fce481f16b8c98caf3a5846db77 ---- /dev/null -+++ b/Tools/Playwright/Configurations/Playwright.xcconfig -@@ -0,0 +1,30 @@ -+// Copyright (C) 2010 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. ``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 -+// 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. -+ -+PRODUCT_NAME = Playwright -+PRODUCT_BUNDLE_IDENTIFIER = org.webkit.$(PRODUCT_NAME:rfc1034identifier) -+GCC_PREFIX_HEADER = mac/Playwright_Prefix.pch -+INFOPLIST_FILE = mac/Info.plist -+EXCLUDED_SOURCE_FILE_NAMES[sdk=iphone*] = * -+OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -framework Cocoa -framework WebKit -+STRIP_STYLE = debugging; -diff --git a/Tools/Playwright/Configurations/SDKVariant.xcconfig b/Tools/Playwright/Configurations/SDKVariant.xcconfig -new file mode 100644 -index 0000000000000000000000000000000000000000..fcdf7e65a67c61fb19ef19c428652f336c180e8e ---- /dev/null -+++ b/Tools/Playwright/Configurations/SDKVariant.xcconfig -@@ -0,0 +1,45 @@ -+// Copyright (C) 2019 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. ``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 -+// 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. -+ -+WK_EMPTY_ = YES; -+WK_NOT_ = YES; -+WK_NOT_YES = NO; -+ -+WK_ALTERNATE_FRAMEWORKS_DIR = $(WK_ALTERNATE_FRAMEWORKS_DIR_$(SDK_VARIANT)); -+WK_ALTERNATE_FRAMEWORKS_DIR_iosmac = /System/iOSSupport; -+WK_USE_ALTERNATE_FRAMEWORKS_DIR = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_FRAMEWORKS_DIR))); -+ -+WK_ALTERNATE_PLATFORM_NAME = $(WK_ALTERNATE_PLATFORM_NAME_$(SDK_VARIANT)); -+WK_ALTERNATE_PLATFORM_NAME_iosmac = maccatalyst; -+WK_USE_ALTERNATE_PLATFORM_NAME = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_PLATFORM_NAME))); -+ -+WK_ALTERNATE_WEBKIT_SDK_PATH = $(WK_ALTERNATE_WEBKIT_SDK_PATH_$(WK_USE_ALTERNATE_FRAMEWORKS_DIR)); -+WK_ALTERNATE_WEBKIT_SDK_PATH_YES = $(WK_ALTERNATE_FRAMEWORKS_DIR)/; -+ -+WK_PLATFORM_NAME = $(WK_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME)); -+WK_PLATFORM_NAME_ALTERNATE_YES = $(WK_ALTERNATE_PLATFORM_NAME); -+WK_PLATFORM_NAME_ALTERNATE_NO = $(PLATFORM_NAME); -+ -+EFFECTIVE_PLATFORM_NAME = $(EFFECTIVE_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME)); -+EFFECTIVE_PLATFORM_NAME_ALTERNATE_YES = -$(WK_ALTERNATE_PLATFORM_NAME); -+EFFECTIVE_PLATFORM_NAME_ALTERNATE_NO = $(EFFECTIVE_PLATFORM_NAME); -diff --git a/Tools/Playwright/MBToolbarItem.h b/Tools/Playwright/MBToolbarItem.h -new file mode 100644 -index 0000000000000000000000000000000000000000..9971d4c1023a9f6e57c6058ae20729e51bb6d503 ---- /dev/null -+++ b/Tools/Playwright/MBToolbarItem.h -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2010 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. -+ */ -+ -+@interface MBToolbarItem : NSToolbarItem -+@end -diff --git a/Tools/Playwright/MBToolbarItem.m b/Tools/Playwright/MBToolbarItem.m -new file mode 100644 -index 0000000000000000000000000000000000000000..56f777891519e820105ae50a86141a534ec4794b ---- /dev/null -+++ b/Tools/Playwright/MBToolbarItem.m -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2010 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 "MBToolbarItem.h" -+ -+@implementation MBToolbarItem -+ -+- (void)validate -+{ -+ [self setEnabled:[[self target] validateUserInterfaceItem:self]]; -+} -+ -+@end -diff --git a/Tools/Playwright/Makefile b/Tools/Playwright/Makefile -new file mode 100644 -index 0000000000000000000000000000000000000000..58e52428388d927ae7681d999e6dd28e0fb3ec6b ---- /dev/null -+++ b/Tools/Playwright/Makefile -@@ -0,0 +1,21 @@ -+# Build Playwright only on SnowLeopard and later. -+ -+OSX_VERSION ?= $(shell sw_vers -productVersion | cut -d. -f 2) -+BUILD_PLAYWRIGHT = $(shell (( $(OSX_VERSION) >= 6 )) && echo "YES" ) -+ -+ifeq "$(BUILD_PLAYWRIGHT)" "YES" -+ -+SCRIPTS_PATH = ../Scripts -+include ../../Makefile.shared -+ -+else -+ -+all: ; -+ -+debug d development dev develop: ; -+ -+release r deployment dep deploy: ; -+ -+clean: ; -+ -+endif -diff --git a/Tools/Playwright/Playwright.xcodeproj/project.pbxproj b/Tools/Playwright/Playwright.xcodeproj/project.pbxproj -new file mode 100644 -index 0000000000000000000000000000000000000000..75a945e72d9fcad94bb89fc6325df18d3259383d ---- /dev/null -+++ b/Tools/Playwright/Playwright.xcodeproj/project.pbxproj -@@ -0,0 +1,264 @@ -+// !$*UTF8*$! -+{ -+ archiveVersion = 1; -+ classes = { -+ }; -+ objectVersion = 46; -+ objects = { -+ -+/* Begin PBXBuildFile section */ -+ 256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF336A /* AppDelegate.m */; }; -+ 51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 51E244F911EFCE07008228D2 /* MBToolbarItem.m */; }; -+ BC329487116A92E2008635D1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329486116A92E2008635D1 /* main.m */; }; -+ BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329497116A941B008635D1 /* BrowserWindowController.m */; }; -+ BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58150DA1D0A300B3202A /* MainMenu.xib */; }; -+ BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC3294A2116A9852008635D1 /* BrowserWindow.xib */; }; -+/* End PBXBuildFile section */ -+ -+/* Begin PBXFileReference section */ -+ 1AFFEF761860EE6800DA465F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; -+ 1AFFEF781860EE6800DA465F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; -+ 1DDD58150DA1D0A300B3202A /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = mac/MainMenu.xib; sourceTree = ""; }; -+ 256AC3D80F4B6AC300CF336A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = mac/AppDelegate.h; sourceTree = ""; }; -+ 256AC3D90F4B6AC300CF336A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = mac/AppDelegate.m; sourceTree = ""; }; -+ 256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Playwright_Prefix.pch; path = mac/Playwright_Prefix.pch; sourceTree = ""; }; -+ 29B97324FDCFA39411CA2CEB /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; -+ 29B97325FDCFA39411CA2CEB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; -+ 37BAF90620218053000EA87A /* Playwright.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Playwright.entitlements; sourceTree = ""; }; -+ 51E244F811EFCE07008228D2 /* MBToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBToolbarItem.h; sourceTree = ""; }; -+ 51E244F911EFCE07008228D2 /* MBToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBToolbarItem.m; sourceTree = ""; }; -+ 8D1107320486CEB800E47091 /* Playwright.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Playwright.app; sourceTree = BUILT_PRODUCTS_DIR; }; -+ A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SDKVariant.xcconfig; sourceTree = ""; }; -+ BC329486116A92E2008635D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = mac/main.m; sourceTree = ""; }; -+ BC329496116A941B008635D1 /* BrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserWindowController.h; path = mac/BrowserWindowController.h; sourceTree = ""; }; -+ BC329497116A941B008635D1 /* BrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserWindowController.m; path = mac/BrowserWindowController.m; sourceTree = ""; }; -+ BC3294A2116A9852008635D1 /* BrowserWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = BrowserWindow.xib; path = mac/BrowserWindow.xib; sourceTree = ""; }; -+ BC72B89A11E57E8A001EB4EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = mac/Info.plist; sourceTree = ""; }; -+ BCA8CBDD11E578A000812FB8 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = ""; }; -+ BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = ""; }; -+ BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Playwright.xcconfig; sourceTree = ""; }; -+/* End PBXFileReference section */ -+ -+/* Begin PBXFrameworksBuildPhase section */ -+ 8D11072E0486CEB800E47091 /* Frameworks */ = { -+ isa = PBXFrameworksBuildPhase; -+ buildActionMask = 2147483647; -+ files = ( -+ ); -+ runOnlyForDeploymentPostprocessing = 0; -+ }; -+/* End PBXFrameworksBuildPhase section */ -+ -+/* Begin PBXGroup section */ -+ 080E96DDFE201D6D7F000002 /* Playwright */ = { -+ isa = PBXGroup; -+ children = ( -+ 256AC3D80F4B6AC300CF336A /* AppDelegate.h */, -+ 256AC3D90F4B6AC300CF336A /* AppDelegate.m */, -+ BC72B89A11E57E8A001EB4EB /* Info.plist */, -+ BC329486116A92E2008635D1 /* main.m */, -+ 51E244F811EFCE07008228D2 /* MBToolbarItem.h */, -+ 51E244F911EFCE07008228D2 /* MBToolbarItem.m */, -+ 37BAF90620218053000EA87A /* Playwright.entitlements */, -+ BC329496116A941B008635D1 /* BrowserWindowController.h */, -+ BC329497116A941B008635D1 /* BrowserWindowController.m */, -+ ); -+ name = Playwright; -+ sourceTree = ""; -+ }; -+ 1058C7A2FEA54F0111CA2CBC /* Other Frameworks */ = { -+ isa = PBXGroup; -+ children = ( -+ 29B97324FDCFA39411CA2CEB /* AppKit.framework */, -+ 1AFFEF781860EE6800DA465F /* CoreData.framework */, -+ 29B97325FDCFA39411CA2CEB /* Foundation.framework */, -+ ); -+ name = "Other Frameworks"; -+ sourceTree = ""; -+ }; -+ 19C28FACFE9D520D11CA2CBC /* Products */ = { -+ isa = PBXGroup; -+ children = ( -+ 8D1107320486CEB800E47091 /* Playwright.app */, -+ ); -+ name = Products; -+ sourceTree = ""; -+ }; -+ 29B97314FDCFA39411CA2CEB /* Playwright */ = { -+ isa = PBXGroup; -+ children = ( -+ 256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */, -+ 080E96DDFE201D6D7F000002 /* Playwright */, -+ 29B97317FDCFA39411CA2CEB /* Resources */, -+ BCA8CBDA11E5787800812FB8 /* Configurations */, -+ 29B97323FDCFA39411CA2CEB /* Frameworks */, -+ 19C28FACFE9D520D11CA2CBC /* Products */, -+ ); -+ name = Playwright; -+ sourceTree = ""; -+ }; -+ 29B97317FDCFA39411CA2CEB /* Resources */ = { -+ isa = PBXGroup; -+ children = ( -+ BC3294A2116A9852008635D1 /* BrowserWindow.xib */, -+ 1DDD58150DA1D0A300B3202A /* MainMenu.xib */, -+ ); -+ name = Resources; -+ sourceTree = ""; -+ }; -+ 29B97323FDCFA39411CA2CEB /* Frameworks */ = { -+ isa = PBXGroup; -+ children = ( -+ 1058C7A2FEA54F0111CA2CBC /* Other Frameworks */, -+ 1AFFEF761860EE6800DA465F /* Cocoa.framework */, -+ ); -+ name = Frameworks; -+ sourceTree = ""; -+ }; -+ BCA8CBDA11E5787800812FB8 /* Configurations */ = { -+ isa = PBXGroup; -+ children = ( -+ BCA8CBDD11E578A000812FB8 /* Base.xcconfig */, -+ BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */, -+ BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */, -+ A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */, -+ ); -+ path = Configurations; -+ sourceTree = ""; -+ }; -+/* End PBXGroup section */ -+ -+/* Begin PBXNativeTarget section */ -+ 8D1107260486CEB800E47091 /* Playwright */ = { -+ isa = PBXNativeTarget; -+ buildConfigurationList = C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */; -+ buildPhases = ( -+ 8D1107290486CEB800E47091 /* Resources */, -+ 8D11072C0486CEB800E47091 /* Sources */, -+ 8D11072E0486CEB800E47091 /* Frameworks */, -+ ); -+ buildRules = ( -+ ); -+ dependencies = ( -+ ); -+ name = Playwright; -+ productInstallPath = "$(HOME)/Applications"; -+ productName = Playwright; -+ productReference = 8D1107320486CEB800E47091 /* Playwright.app */; -+ productType = "com.apple.product-type.application"; -+ }; -+/* End PBXNativeTarget section */ -+ -+/* Begin PBXProject section */ -+ 29B97313FDCFA39411CA2CEC /* Project object */ = { -+ isa = PBXProject; -+ attributes = { -+ LastSwiftUpdateCheck = 0700; -+ LastUpgradeCheck = 1000; -+ TargetAttributes = { -+ 8D1107260486CEB800E47091 = { -+ SystemCapabilities = { -+ com.apple.Sandbox = { -+ enabled = 1; -+ }; -+ }; -+ }; -+ }; -+ }; -+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */; -+ compatibilityVersion = "Xcode 3.2"; -+ developmentRegion = en; -+ hasScannedForEncodings = 1; -+ knownRegions = ( -+ en, -+ ); -+ mainGroup = 29B97314FDCFA39411CA2CEB /* Playwright */; -+ projectDirPath = ""; -+ projectRoot = ""; -+ targets = ( -+ 8D1107260486CEB800E47091 /* Playwright */, -+ ); -+ }; -+/* End PBXProject section */ -+ -+/* Begin PBXResourcesBuildPhase section */ -+ 8D1107290486CEB800E47091 /* Resources */ = { -+ isa = PBXResourcesBuildPhase; -+ buildActionMask = 2147483647; -+ files = ( -+ BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */, -+ BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */, -+ ); -+ runOnlyForDeploymentPostprocessing = 0; -+ }; -+/* End PBXResourcesBuildPhase section */ -+ -+/* Begin PBXSourcesBuildPhase section */ -+ 8D11072C0486CEB800E47091 /* Sources */ = { -+ isa = PBXSourcesBuildPhase; -+ buildActionMask = 2147483647; -+ files = ( -+ 256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */, -+ BC329487116A92E2008635D1 /* main.m in Sources */, -+ 51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */, -+ BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */, -+ ); -+ runOnlyForDeploymentPostprocessing = 0; -+ }; -+/* End PBXSourcesBuildPhase section */ -+ -+/* Begin XCBuildConfiguration section */ -+ C01FCF4B08A954540054247C /* Debug */ = { -+ isa = XCBuildConfiguration; -+ baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */; -+ buildSettings = { -+ }; -+ name = Debug; -+ }; -+ C01FCF4C08A954540054247B /* Release */ = { -+ isa = XCBuildConfiguration; -+ baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */; -+ buildSettings = { -+ }; -+ name = Release; -+ }; -+ C01FCF4F08A954540054247C /* Debug */ = { -+ isa = XCBuildConfiguration; -+ baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */; -+ buildSettings = { -+ GCC_OPTIMIZATION_LEVEL = 0; -+ }; -+ name = Debug; -+ }; -+ C01FCF5008A954540054247C /* Release */ = { -+ isa = XCBuildConfiguration; -+ baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */; -+ buildSettings = { -+ }; -+ name = Release; -+ }; -+/* End XCBuildConfiguration section */ -+ -+/* Begin XCConfigurationList section */ -+ C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */ = { -+ isa = XCConfigurationList; -+ buildConfigurations = ( -+ C01FCF4B08A954540054247C /* Debug */, -+ C01FCF4C08A954540054247B /* Release */, -+ ); -+ defaultConfigurationIsVisible = 0; -+ defaultConfigurationName = Release; -+ }; -+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */ = { -+ isa = XCConfigurationList; -+ buildConfigurations = ( -+ C01FCF4F08A954540054247C /* Debug */, -+ C01FCF5008A954540054247C /* Release */, -+ ); -+ defaultConfigurationIsVisible = 0; -+ defaultConfigurationName = Release; -+ }; -+/* End XCConfigurationList section */ -+ }; -+ rootObject = 29B97313FDCFA39411CA2CEC /* Project object */; -+} -diff --git a/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme b/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme -new file mode 100644 -index 0000000000000000000000000000000000000000..00fb6b0006c743091a8bbf8edb18b21192ea7d6c ---- /dev/null -+++ b/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme -@@ -0,0 +1,78 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/Tools/Playwright/mac/AppDelegate.h b/Tools/Playwright/mac/AppDelegate.h -new file mode 100644 -index 0000000000000000000000000000000000000000..ccc73af47f7bdb4813a9a1e6fb8d55d5d837c8d7 ---- /dev/null -+++ b/Tools/Playwright/mac/AppDelegate.h -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2010 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 -+#import -+ -+@interface WebViewDialog : NSObject -+@property (nonatomic, strong) WKWebView *webView; -+@property (nonatomic, copy) void (^completionHandler)(BOOL accept, NSString* value); -+@end -+ -+@interface BrowserAppDelegate : NSObject { -+ NSMutableSet *_headlessWindows; -+ NSMutableSet *_browserContexts; -+ bool _headless; -+ bool _noStartupWindow; -+ NSMutableSet *_dialogs; -+ NSString* _initialURL; -+ NSString* _userDataDir; -+ IBOutlet NSMenuItem *_newWebKit2WindowItem; -+} -+ -+@end -+ -+@interface NSApplication (PlaywrightApplicationExtensions) -+ -+- (BrowserAppDelegate *)browserAppDelegate; -+ -+@end -diff --git a/Tools/Playwright/mac/AppDelegate.m b/Tools/Playwright/mac/AppDelegate.m -new file mode 100644 -index 0000000000000000000000000000000000000000..d46e0dbe9677760b63de22b837a08404a8042dd2 ---- /dev/null -+++ b/Tools/Playwright/mac/AppDelegate.m -@@ -0,0 +1,405 @@ -+/* -+ * Copyright (C) 2010-2016 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 "AppDelegate.h" -+ -+#import "BrowserWindowController.h" -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+ -+@implementation NSApplication (PlaywrightApplicationExtensions) -+ -+- (BrowserAppDelegate *)browserAppDelegate -+{ -+ return (BrowserAppDelegate *)[self delegate]; -+} -+ -+@end -+ -+@interface NSApplication (TouchBar) -+@property (getter=isAutomaticCustomizeTouchBarMenuItemEnabled) BOOL automaticCustomizeTouchBarMenuItemEnabled; -+ -+@property (readonly, nonatomic) WKWebViewConfiguration *defaultConfiguration; -+ -+@end -+ -+@implementation WebViewDialog -+- (void)dealloc -+{ -+ [_webView release]; -+ _webView = nil; -+ [super dealloc]; -+} -+@end -+ -+enum { -+ _NSBackingStoreUnbuffered = 3 -+}; -+ -+NSString* const ActivityReason = @"Batch headless process"; -+const NSActivityOptions ActivityOptions = -+ (NSActivityUserInitiatedAllowingIdleSystemSleep | -+ NSActivityLatencyCritical) & -+ ~(NSActivitySuddenTerminationDisabled | -+ NSActivityAutomaticTerminationDisabled); -+ -+@implementation BrowserAppDelegate -+ -+- (id)init -+{ -+ self = [super init]; -+ -+ if (!self) -+ return nil; -+ -+ _initialURL = nil; -+ _userDataDir = nil; -+ NSArray *arguments = [[NSProcessInfo processInfo] arguments]; -+ NSRange subargs = NSMakeRange(1, [arguments count] - 1); -+ NSArray *subArray = [arguments subarrayWithRange:subargs]; -+ -+ for (NSString *argument in subArray) { -+ if (![argument hasPrefix:@"--"]) -+ _initialURL = argument; -+ if ([argument hasPrefix:@"--user-data-dir="]) { -+ NSRange range = NSMakeRange(16, [argument length] - 16); -+ _userDataDir = [[argument substringWithRange:range] copy]; -+ } -+ } -+ -+ _headless = [arguments containsObject: @"--headless"]; -+ _noStartupWindow = [arguments containsObject: @"--no-startup-window"]; -+ _browserContexts = [[NSMutableSet alloc] init]; -+ -+ if (_headless) { -+ _headlessWindows = [[NSMutableSet alloc] init]; -+ [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; -+ [[NSProcessInfo processInfo] beginActivityWithOptions:ActivityOptions -+ reason:ActivityReason]; -+ _dialogs = [[NSMutableSet alloc] init]; -+ } else { -+ [NSApp activateIgnoringOtherApps:YES]; -+ } -+ if ([arguments containsObject: @"--inspector-pipe"]) -+ [_WKBrowserInspector initializeRemoteInspectorPipe:self headless:_headless]; -+ return self; -+} -+ -+- (void)awakeFromNib -+{ -+ if ([NSApp respondsToSelector:@selector(setAutomaticCustomizeTouchBarMenuItemEnabled:)]) -+ [NSApp setAutomaticCustomizeTouchBarMenuItemEnabled:YES]; -+} -+ -+- (WKWebsiteDataStore *)persistentDataStore -+{ -+ static WKWebsiteDataStore *dataStore; -+ -+ if (!dataStore) { -+ _WKWebsiteDataStoreConfiguration *configuration = [[[_WKWebsiteDataStoreConfiguration alloc] init] autorelease]; -+ if (_userDataDir) { -+ NSURL *cookieFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/cookie.db", _userDataDir]]; -+ [configuration _setCookieStorageFile:cookieFile]; -+ -+ NSURL *applicationCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ApplicationCache", _userDataDir]]; -+ [configuration setApplicationCacheDirectory:applicationCacheDirectory]; -+ -+ NSURL *cacheStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/CacheStorage", _userDataDir]]; -+ [configuration _setCacheStorageDirectory:cacheStorageDirectory]; -+ -+ NSURL *indexedDBDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/IndexedDB", _userDataDir]]; -+ [configuration _setIndexedDBDatabaseDirectory:indexedDBDirectory]; -+ -+ NSURL *localStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/LocalStorage", _userDataDir]]; -+ [configuration _setWebStorageDirectory:localStorageDirectory]; -+ -+ NSURL *mediaCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaCache", _userDataDir]]; -+ [configuration setMediaCacheDirectory:mediaCacheDirectory]; -+ -+ NSURL *mediaKeysDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaKeys", _userDataDir]]; -+ [configuration setMediaKeysStorageDirectory:mediaKeysDirectory]; -+ -+ NSURL *networkCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/NetworkCache", _userDataDir]]; -+ [configuration setNetworkCacheDirectory:networkCacheDirectory]; -+ -+ NSURL *loadStatsDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ResourceLoadStatistics", _userDataDir]]; -+ [configuration _setResourceLoadStatisticsDirectory:loadStatsDirectory]; -+ -+ NSURL *serviceWorkersDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ServiceWorkers", _userDataDir]]; -+ [configuration _setServiceWorkerRegistrationDirectory:serviceWorkersDirectory]; -+ -+ NSURL *webSqlDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/WebSQL", _userDataDir]]; -+ [configuration _setWebSQLDatabaseDirectory:webSqlDirectory]; -+ } -+ dataStore = [[WKWebsiteDataStore alloc] _initWithConfiguration:configuration]; -+ } -+ -+ return dataStore; -+} -+ -+- (WKWebViewConfiguration *)defaultConfiguration -+{ -+ static WKWebViewConfiguration *configuration; -+ -+ if (!configuration) { -+ configuration = [[WKWebViewConfiguration alloc] init]; -+ configuration.websiteDataStore = [self persistentDataStore]; -+ configuration.preferences._fullScreenEnabled = YES; -+ configuration.preferences._developerExtrasEnabled = YES; -+ configuration.preferences._mediaDevicesEnabled = YES; -+ configuration.preferences._mockCaptureDevicesEnabled = YES; -+ configuration.preferences._hiddenPageDOMTimerThrottlingEnabled = NO; -+ configuration.preferences._hiddenPageDOMTimerThrottlingAutoIncreases = NO; -+ configuration.preferences._pageVisibilityBasedProcessSuppressionEnabled = NO; -+ configuration.preferences._domTimersThrottlingEnabled = NO; -+ configuration.preferences._requestAnimationFrameEnabled = YES; -+ _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; -+ processConfiguration.forceOverlayScrollbars = YES; -+ configuration.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration AndDataStore:configuration.websiteDataStore] autorelease]; -+ } -+ return configuration; -+} -+ -+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -+{ -+ if (!_headless) -+ [self _updateNewWindowKeyEquivalents]; -+ -+ if (_noStartupWindow) -+ return; -+ -+ [self createNewPage:0]; -+ _initialURL = nil; -+} -+ -+- (void)_updateNewWindowKeyEquivalents -+{ -+ NSString *normalWindowEquivalent = @"n"; -+ _newWebKit2WindowItem.keyEquivalentModifierMask = NSEventModifierFlagCommand; -+ _newWebKit2WindowItem.keyEquivalent = normalWindowEquivalent; -+} -+ -+#pragma mark WKBrowserInspectorDelegate -+ -+- (WKWebViewConfiguration *) sessionConfiguration:(uint64_t)sessionID -+{ -+ for (_WKBrowserContext *browserContext in _browserContexts) { -+ if ([[browserContext dataStore] sessionID] != sessionID) -+ continue; -+ WKWebViewConfiguration *configuration = [[[self defaultConfiguration] copy] autorelease]; -+ configuration.websiteDataStore = [browserContext dataStore]; -+ configuration.processPool = [browserContext processPool]; -+ return configuration; -+ } -+ return [self defaultConfiguration]; -+} -+ -+- (WKWebView *)createNewPage:(uint64_t)sessionID -+{ -+ NSString* urlString = _initialURL ? _initialURL : @"about:blank"; -+ WKWebViewConfiguration *configuration = [self sessionConfiguration:sessionID]; -+ if (_headless) -+ return [self createHeadlessPage:configuration withURL:urlString]; -+ return [self createHeadfulPage:configuration withURL:urlString]; -+} -+ -+- (WKWebView *)createHeadfulPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString -+{ -+ // WebView lifecycle will control the BrowserWindowController life times. -+ BrowserWindowController *controller = [[BrowserWindowController alloc] initWithConfiguration:configuration]; -+ if (!controller) -+ return nil; -+ [controller loadURLString:urlString]; -+ return [controller webView]; -+} -+ -+- (WKWebView *)createHeadlessPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString -+{ -+ NSRect rect = NSMakeRect(0, 0, 1280, 720); -+ NSScreen *firstScreen = [[NSScreen screens] objectAtIndex:0]; -+ NSRect windowRect = NSOffsetRect(rect, -10000, [firstScreen frame].size.height - rect.size.height + 10000); -+ NSWindow* window = [[NSWindow alloc] initWithContentRect:windowRect styleMask:NSWindowStyleMaskBorderless backing:(NSBackingStoreType)_NSBackingStoreUnbuffered defer:YES]; -+ -+ WKWebView* webView = [[WKWebView alloc] initWithFrame:[window.contentView bounds] configuration:configuration]; -+ webView._windowOcclusionDetectionEnabled = NO; -+ if (!webView) -+ return nil; -+ -+ webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; -+ [window.contentView addSubview:webView]; -+ if (urlString) { -+ NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlString]; -+ [webView loadRequest:[NSURLRequest requestWithURL:url]]; -+ } -+ [_headlessWindows addObject:window]; -+ webView.navigationDelegate = self; -+ webView.UIDelegate = self; -+ return [webView autorelease]; -+} -+ -+- (_WKBrowserContext *)createBrowserContext -+{ -+ _WKBrowserContext *browserContext = [[_WKBrowserContext alloc] init]; -+ _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; -+ processConfiguration.forceOverlayScrollbars = YES; -+ browserContext.dataStore = [WKWebsiteDataStore nonPersistentDataStore]; -+ browserContext.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease]; -+ [browserContext.processPool _setDownloadDelegate:self]; -+ [_browserContexts addObject:browserContext]; -+ return browserContext; -+} -+ -+- (void)deleteBrowserContext:(uint64_t)sessionID -+{ -+ for (_WKBrowserContext *browserContext in _browserContexts) { -+ if ([[browserContext dataStore] sessionID] != sessionID) -+ continue; -+ [_browserContexts removeObject:browserContext]; -+ return; -+ } -+} -+ -+- (void)quit -+{ -+ [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; -+} -+ -+#pragma mark WKUIDelegate -+ -+- (void)webViewDidClose:(WKWebView *)webView { -+ for (NSWindow *window in _headlessWindows) { -+ if (webView.window != window) -+ continue; -+ [webView removeFromSuperview]; -+ [window close]; -+ [_headlessWindows removeObject:window]; -+ break; -+ } -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler -+{ -+ WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; -+ dialog.webView = webView; -+ dialog.completionHandler = ^void (BOOL accept, NSString* value) { -+ completionHandler(); -+ }; -+ [_dialogs addObject:dialog]; -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler -+{ -+ WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; -+ dialog.webView = webView; -+ dialog.completionHandler = ^void (BOOL accept, NSString* value) { -+ completionHandler(accept); -+ }; -+ [_dialogs addObject:dialog]; -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler -+{ -+ WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; -+ dialog.webView = webView; -+ dialog.completionHandler = ^void (BOOL accept, NSString* value) { -+ completionHandler(accept && value ? value : nil); -+ }; -+ [_dialogs addObject:dialog]; -+} -+ -+- (void)_webView:(WKWebView *)webView runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler -+{ -+ WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; -+ dialog.webView = webView; -+ dialog.completionHandler = ^void (BOOL accept, NSString* value) { -+ completionHandler(accept); -+ }; -+ [_dialogs addObject:dialog]; -+} -+ -+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value -+{ -+ for (WebViewDialog *dialog in _dialogs) { -+ if (dialog.webView != webView) -+ continue; -+ dialog.completionHandler(accept, value); -+ [_dialogs removeObject:dialog]; -+ break; -+ } -+} -+ -+- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures -+{ -+ return [self createHeadlessPage:configuration withURL:nil]; -+} -+ -+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler -+{ -+ LOG(@"decidePolicyForNavigationAction"); -+ -+ if (navigationAction._canHandleRequest) { -+ decisionHandler(WKNavigationActionPolicyAllow); -+ return; -+ } -+ decisionHandler(WKNavigationActionPolicyCancel); -+} -+ -+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler -+{ -+ if (![navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { -+ decisionHandler(WKNavigationResponsePolicyAllow); -+ return; -+ } -+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)navigationResponse.response; -+ -+ NSString *disposition = [[httpResponse allHeaderFields] objectForKey:@"Content-Disposition"]; -+ if (disposition && [disposition hasPrefix:@"attachment"]) { -+ decisionHandler(_WKNavigationResponsePolicyBecomeDownload); -+ return; -+ } -+ decisionHandler(WKNavigationResponsePolicyAllow); -+} -+ -+#pragma mark _WKDownloadDelegate -+ -+- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler -+{ -+ completionHandler(NO, @""); -+} -+ -+@end -diff --git a/Tools/Playwright/mac/BrowserWindow.xib b/Tools/Playwright/mac/BrowserWindow.xib -new file mode 100644 -index 0000000000000000000000000000000000000000..f6f3d8e3a0f163e61b2f3d54819e9d25a0a3eb75 ---- /dev/null -+++ b/Tools/Playwright/mac/BrowserWindow.xib -@@ -0,0 +1,153 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/Tools/Playwright/mac/BrowserWindowController.h b/Tools/Playwright/mac/BrowserWindowController.h -new file mode 100644 -index 0000000000000000000000000000000000000000..4dbf13c8fb31a745ae8e1965a457d4fbcd8e5866 ---- /dev/null -+++ b/Tools/Playwright/mac/BrowserWindowController.h -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2010 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. -+ */ -+ -+@class WKWebView; -+ -+@interface BrowserWindowController : NSWindowController -+ -+- (IBAction)goBack:(id)sender; -+- (IBAction)goForward:(id)sender; -+- (IBAction)reload:(id)sender; -+- (IBAction)saveAsPDF:(id)sender; -+- (IBAction)saveAsWebArchive:(id)sender; -+- (IBAction)zoomIn:(id)sender; -+- (IBAction)zoomOut:(id)sender; -+- (IBAction)resetZoom:(id)sender; -+- (IBAction)showHideWebInspector:(id)sender; -+ -+- (IBAction)setPageScale:(id)sender; -+- (IBAction)setViewScale:(id)sender; -+- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration; -+- (void)loadURLString:(NSString *)urlString; -+- (WKWebView *)webView; -+ -+@end -diff --git a/Tools/Playwright/mac/BrowserWindowController.m b/Tools/Playwright/mac/BrowserWindowController.m -new file mode 100644 -index 0000000000000000000000000000000000000000..c48697f7cfd699e3da720be6d9e4d0db90726984 ---- /dev/null -+++ b/Tools/Playwright/mac/BrowserWindowController.m -@@ -0,0 +1,839 @@ -+/* -+ * Copyright (C) 2010-2016 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 "BrowserWindowController.h" -+ -+#import "AppDelegate.h" -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+ -+static void* keyValueObservingContext = &keyValueObservingContext; -+ -+@interface PlaywrightNSTextFinder : NSTextFinder -+ -+@property (nonatomic, copy) dispatch_block_t hideInterfaceCallback; -+ -+@end -+ -+@implementation PlaywrightNSTextFinder -+ -+- (void)performAction:(NSTextFinderAction)op -+{ -+ [super performAction:op]; -+ -+ if (op == NSTextFinderActionHideFindInterface && _hideInterfaceCallback) -+ _hideInterfaceCallback(); -+} -+ -+@end -+ -+@interface BrowserWindowController () -+@end -+ -+@implementation BrowserWindowController { -+ IBOutlet NSProgressIndicator *progressIndicator; -+ IBOutlet NSButton *reloadButton; -+ IBOutlet NSButton *backButton; -+ IBOutlet NSButton *forwardButton; -+ IBOutlet NSButton *share; -+ IBOutlet NSToolbar *toolbar; -+ IBOutlet NSTextField *urlText; -+ IBOutlet NSView *containerView; -+ IBOutlet NSButton *toggleUseShrinkToFitButton; -+ -+ WKWebViewConfiguration *_configuration; -+ WKWebView *_webView; -+ BOOL _zoomTextOnly; -+ BOOL _isPrivateBrowsingWindow; -+ NSAlert* _alert; -+ -+ BOOL _useShrinkToFit; -+ -+ PlaywrightNSTextFinder *_textFinder; -+ NSView *_textFindBarView; -+ BOOL _findBarVisible; -+} -+ -+- (id)initWithWindow:(NSWindow *)window -+{ -+ self = [super initWithWindow:window]; -+ return self; -+} -+ -+- (void)windowDidLoad -+{ -+ [share sendActionOn:NSEventMaskLeftMouseDown]; -+ [super windowDidLoad]; -+} -+ -+- (IBAction)openLocation:(id)sender -+{ -+ [[self window] makeFirstResponder:urlText]; -+} -+ -+- (NSString *)addProtocolIfNecessary:(NSString *)address -+{ -+ if ([address rangeOfString:@"://"].length > 0) -+ return address; -+ -+ if ([address hasPrefix:@"data:"]) -+ return address; -+ -+ if ([address hasPrefix:@"about:"]) -+ return address; -+ -+ return [@"http://" stringByAppendingString:address]; -+} -+ -+- (IBAction)share:(id)sender -+{ -+ NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:@[ self.currentURL ]]; -+ picker.delegate = self; -+ [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSRectEdgeMinY]; -+} -+ -+- (IBAction)showHideWebView:(id)sender -+{ -+ self.mainContentView.hidden = !self.mainContentView.isHidden; -+} -+ -+- (CGFloat)pageScaleForMenuItemTag:(NSInteger)tag -+{ -+ if (tag == 1) -+ return 1; -+ if (tag == 2) -+ return 1.25; -+ if (tag == 3) -+ return 1.5; -+ if (tag == 4) -+ return 2.0; -+ -+ return 1; -+} -+ -+- (void)awakeFromNib -+{ -+ _webView = [[WKWebView alloc] initWithFrame:[containerView bounds] configuration:_configuration]; -+ _webView._windowOcclusionDetectionEnabled = NO; -+ -+ _webView.allowsMagnification = YES; -+ _webView.allowsBackForwardNavigationGestures = YES; -+ -+ [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; -+ [containerView addSubview:_webView]; -+ -+ [progressIndicator bind:NSHiddenBinding toObject:_webView withKeyPath:@"loading" options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }]; -+ [progressIndicator bind:NSValueBinding toObject:_webView withKeyPath:@"estimatedProgress" options:nil]; -+ -+ [_webView addObserver:self forKeyPath:@"title" options:0 context:keyValueObservingContext]; -+ [_webView addObserver:self forKeyPath:@"URL" options:0 context:keyValueObservingContext]; -+ -+ _webView.navigationDelegate = self; -+ _webView.UIDelegate = self; -+ -+ _webView._observedRenderingProgressEvents = _WKRenderingProgressEventFirstLayout -+ | _WKRenderingProgressEventFirstVisuallyNonEmptyLayout -+ | _WKRenderingProgressEventFirstPaintWithSignificantArea -+ | _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering -+ | _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering; -+ -+ _webView.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15"; -+ -+ _webView._usePlatformFindUI = NO; -+ -+ _textFinder = [[PlaywrightNSTextFinder alloc] init]; -+ _textFinder.incrementalSearchingEnabled = YES; -+ _textFinder.incrementalSearchingShouldDimContentView = NO; -+ _textFinder.client = _webView; -+ _textFinder.findBarContainer = self; -+ _textFinder.hideInterfaceCallback = ^{ -+ [_webView _hideFindUI]; -+ }; -+ -+ _zoomTextOnly = NO; -+} -+ -+- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration -+{ -+ if (!(self = [super initWithWindowNibName:@"BrowserWindow"])) -+ return nil; -+ _configuration = [configuration copy]; -+ _isPrivateBrowsingWindow = !_configuration.websiteDataStore.isPersistent; -+ self.window.styleMask &= ~NSWindowStyleMaskFullSizeContentView; -+ [self.window makeKeyAndOrderFront:nil]; -+ return self; -+} -+ -+- (void)dealloc -+{ -+ [[NSNotificationCenter defaultCenter] removeObserver:self]; -+ -+ [progressIndicator unbind:NSHiddenBinding]; -+ [progressIndicator unbind:NSValueBinding]; -+ -+ [_textFinder release]; -+ [_webView release]; -+ [_configuration release]; -+ -+ [super dealloc]; -+} -+ -+- (IBAction)fetch:(id)sender -+{ -+ [urlText setStringValue:[self addProtocolIfNecessary:urlText.stringValue]]; -+ NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlText.stringValue]; -+ [_webView loadRequest:[NSURLRequest requestWithURL:url]]; -+} -+ -+- (IBAction)setPageScale:(id)sender -+{ -+ CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]]; -+ [_webView _setPageScale:scale withOrigin:CGPointZero]; -+} -+ -+- (CGFloat)viewScaleForMenuItemTag:(NSInteger)tag -+{ -+ if (tag == 1) -+ return 1; -+ if (tag == 2) -+ return 0.75; -+ if (tag == 3) -+ return 0.5; -+ if (tag == 4) -+ return 0.25; -+ -+ return 1; -+} -+ -+- (IBAction)setViewScale:(id)sender -+{ -+ CGFloat scale = [self viewScaleForMenuItemTag:[sender tag]]; -+ CGFloat oldScale = [_webView _viewScale]; -+ -+ if (scale == oldScale) -+ return; -+ -+ [_webView _setLayoutMode:_WKLayoutModeDynamicSizeComputedFromViewScale]; -+ -+ NSRect oldFrame = self.window.frame; -+ NSSize newFrameSize = NSMakeSize(oldFrame.size.width * (scale / oldScale), oldFrame.size.height * (scale / oldScale)); -+ [self.window setFrame:NSMakeRect(oldFrame.origin.x, oldFrame.origin.y - (newFrameSize.height - oldFrame.size.height), newFrameSize.width, newFrameSize.height) display:NO animate:NO]; -+ -+ [_webView _setViewScale:scale]; -+} -+ -+static BOOL areEssentiallyEqual(double a, double b) -+{ -+ double tolerance = 0.001; -+ return (fabs(a - b) <= tolerance); -+} -+ -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wdeprecated-implementations" -+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem -+#pragma GCC diagnostic pop -+{ -+ SEL action = menuItem.action; -+ -+ if (action == @selector(saveAsPDF:)) -+ return YES; -+ if (action == @selector(saveAsWebArchive:)) -+ return YES; -+ -+ if (action == @selector(zoomIn:)) -+ return [self canZoomIn]; -+ if (action == @selector(zoomOut:)) -+ return [self canZoomOut]; -+ if (action == @selector(resetZoom:)) -+ return [self canResetZoom]; -+ -+ if (action == @selector(toggleZoomMode:)) -+ [menuItem setState:_zoomTextOnly ? NSControlStateValueOn : NSControlStateValueOff]; -+ else if (action == @selector(showHideWebInspector:)) -+ [menuItem setTitle:_webView._inspector.isVisible ? @"Close Web Inspector" : @"Show Web Inspector"]; -+ -+ if (action == @selector(setPageScale:)) -+ [menuItem setState:areEssentiallyEqual([_webView _pageScale], [self pageScaleForMenuItemTag:[menuItem tag]])]; -+ -+ if (action == @selector(setViewScale:)) -+ [menuItem setState:areEssentiallyEqual([_webView _viewScale], [self viewScaleForMenuItemTag:[menuItem tag]])]; -+ -+ return YES; -+} -+ -+- (IBAction)reload:(id)sender -+{ -+ [_webView reload]; -+} -+ -+- (IBAction)goBack:(id)sender -+{ -+ [_webView goBack]; -+} -+ -+- (IBAction)goForward:(id)sender -+{ -+ [_webView goForward]; -+} -+ -+- (IBAction)toggleZoomMode:(id)sender -+{ -+ if (_zoomTextOnly) { -+ _zoomTextOnly = NO; -+ double currentTextZoom = _webView._textZoomFactor; -+ _webView._textZoomFactor = 1; -+ _webView.pageZoom = currentTextZoom; -+ } else { -+ _zoomTextOnly = YES; -+ double currentPageZoom = _webView._pageZoomFactor; -+ _webView._textZoomFactor = currentPageZoom; -+ _webView.pageZoom = 1; -+ } -+} -+ -+- (IBAction)resetZoom:(id)sender -+{ -+ if (![self canResetZoom]) -+ return; -+ -+ if (_zoomTextOnly) -+ _webView._textZoomFactor = 1; -+ else -+ _webView.pageZoom = 1; -+} -+ -+- (BOOL)canResetZoom -+{ -+ return _zoomTextOnly ? (_webView._textZoomFactor != 1) : (_webView.pageZoom != 1); -+} -+ -+- (IBAction)showHideWebInspector:(id)sender -+{ -+ _WKInspector *inspector = _webView._inspector; -+ if (inspector.isVisible) -+ [inspector hide]; -+ else -+ [inspector show]; -+} -+ -+- (NSURL *)currentURL -+{ -+ return _webView.URL; -+} -+ -+- (NSView *)mainContentView -+{ -+ return _webView; -+} -+ -+- (BOOL)validateUserInterfaceItem:(id )item -+{ -+ SEL action = item.action; -+ -+ if (action == @selector(goBack:) || action == @selector(goForward:)) -+ return [_webView validateUserInterfaceItem:item]; -+ -+ return YES; -+} -+ -+- (void)validateToolbar -+{ -+ [toolbar validateVisibleItems]; -+} -+ -+- (BOOL)windowShouldClose:(id)sender -+{ -+ return YES; -+} -+ -+- (void)windowWillClose:(NSNotification *)notification -+{ -+ [_webView removeObserver:self forKeyPath:@"title"]; -+ [_webView removeObserver:self forKeyPath:@"URL"]; -+ [_webView removeFromSuperview]; -+ _textFinder.hideInterfaceCallback = nil; -+ [self release]; -+} -+ -+- (void)webViewDidClose:(WKWebView *)webView { -+ [self.window close]; -+} -+ -+#define DefaultMinimumZoomFactor (.5) -+#define DefaultMaximumZoomFactor (3.0) -+#define DefaultZoomFactorRatio (1.2) -+ -+- (CGFloat)currentZoomFactor -+{ -+ return _zoomTextOnly ? _webView._textZoomFactor : _webView.pageZoom; -+} -+ -+- (void)setCurrentZoomFactor:(CGFloat)factor -+{ -+ if (_zoomTextOnly) -+ _webView._textZoomFactor = factor; -+ else -+ _webView.pageZoom = factor; -+} -+ -+- (BOOL)canZoomIn -+{ -+ return self.currentZoomFactor * DefaultZoomFactorRatio < DefaultMaximumZoomFactor; -+} -+ -+- (void)zoomIn:(id)sender -+{ -+ if (!self.canZoomIn) -+ return; -+ -+ self.currentZoomFactor *= DefaultZoomFactorRatio; -+} -+ -+- (BOOL)canZoomOut -+{ -+ return self.currentZoomFactor / DefaultZoomFactorRatio > DefaultMinimumZoomFactor; -+} -+ -+- (void)zoomOut:(id)sender -+{ -+ if (!self.canZoomIn) -+ return; -+ -+ self.currentZoomFactor /= DefaultZoomFactorRatio; -+} -+ -+- (void)updateTitle:(NSString *)title -+{ -+ if (!title) { -+ NSURL *url = _webView.URL; -+ title = url.lastPathComponent ?: url._web_userVisibleString; -+ } -+ -+ self.window.title = [NSString stringWithFormat:@"%@%@ [%d]%@", _isPrivateBrowsingWindow ? @"🙈 " : @"", title, _webView._webProcessIdentifier, @""]; -+} -+ -+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -+{ -+ if (context != keyValueObservingContext || object != _webView) -+ return; -+ -+ if ([keyPath isEqualToString:@"title"]) -+ [self updateTitle:_webView.title]; -+ else if ([keyPath isEqualToString:@"URL"]) -+ [self updateTextFieldFromURL:_webView.URL]; -+} -+ -+- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures -+{ -+ // WebView lifecycle will control the BrowserWindowController life times. -+ BrowserWindowController *controller = [[BrowserWindowController alloc] initWithConfiguration:configuration]; -+ return controller->_webView; -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler -+{ -+ NSAlert* alert = [[NSAlert alloc] init]; -+ -+ [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [frame.request.URL absoluteString]]]; -+ [alert setInformativeText:message]; -+ [alert addButtonWithTitle:@"OK"]; -+ -+ _alert = alert; -+ [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { -+ completionHandler(); -+ [alert release]; -+ _alert = nil; -+ }]; -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler -+{ -+ NSAlert* alert = [[NSAlert alloc] init]; -+ -+ [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [frame.request.URL absoluteString]]]; -+ [alert setInformativeText:message]; -+ -+ [alert addButtonWithTitle:@"OK"]; -+ [alert addButtonWithTitle:@"Cancel"]; -+ -+ _alert = alert; -+ [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { -+ completionHandler(response == NSAlertFirstButtonReturn); -+ [alert release]; -+ _alert = nil; -+ }]; -+} -+ -+- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler -+{ -+ NSAlert* alert = [[NSAlert alloc] init]; -+ -+ [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [frame.request.URL absoluteString]]]; -+ [alert setInformativeText:prompt]; -+ -+ [alert addButtonWithTitle:@"OK"]; -+ [alert addButtonWithTitle:@"Cancel"]; -+ -+ NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; -+ [input setStringValue:defaultText]; -+ [alert setAccessoryView:input]; -+ -+ _alert = alert; -+ [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { -+ [input validateEditing]; -+ completionHandler(response == NSAlertFirstButtonReturn ? [input stringValue] : nil); -+ [alert release]; -+ _alert = nil; -+ }]; -+} -+ -+- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value -+{ -+ if (!_alert) -+ return; -+ NSTextField* input = (NSTextField*)_alert.accessoryView; -+ if (accept && input && value) -+ [input setStringValue:value]; -+ [self.window endSheet:_alert.window returnCode: accept ? NSAlertFirstButtonReturn : NSModalResponseCancel]; -+} -+ -+#if __has_feature(objc_generics) -+- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray * URLs))completionHandler -+#else -+- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler -+#endif -+{ -+ NSOpenPanel *openPanel = [NSOpenPanel openPanel]; -+ -+ openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection; -+ -+ [openPanel beginSheetModalForWindow:webView.window completionHandler:^(NSInteger result) { -+ if (result == NSModalResponseOK) -+ completionHandler(openPanel.URLs); -+ else -+ completionHandler(nil); -+ }]; -+} -+ -+- (void)_webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler -+{ -+ NSAlert *alert = [[NSAlert alloc] init]; -+ -+ alert.messageText = [NSString stringWithFormat:@"JavaScript before unload dialog from %@.", [frame.request.URL absoluteString]]; -+ alert.informativeText = message; -+ -+ [alert addButtonWithTitle:@"Leave Page"]; -+ [alert addButtonWithTitle:@"Stay On Page"]; -+ -+ _alert = alert; -+ [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { -+ completionHandler(response == NSAlertFirstButtonReturn); -+ [alert release]; -+ _alert = nil; -+ }]; -+} -+ -+- (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo -+{ -+ return WKDragDestinationActionAny; -+} -+ -+- (void)updateTextFieldFromURL:(NSURL *)URL -+{ -+ if (!URL) -+ return; -+ -+ if (!URL.absoluteString.length) -+ return; -+ -+ urlText.stringValue = [URL _web_userVisibleString]; -+} -+ -+- (void)loadURLString:(NSString *)urlString -+{ -+ // FIXME: We shouldn't have to set the url text here. -+ [urlText setStringValue:urlString]; -+ [self fetch:nil]; -+} -+ -+- (void)loadHTMLString:(NSString *)HTMLString -+{ -+ [_webView loadHTMLString:HTMLString baseURL:nil]; -+} -+ -+static NSSet *dataTypes() -+{ -+ return [WKWebsiteDataStore allWebsiteDataTypes]; -+} -+ -+- (IBAction)fetchWebsiteData:(id)sender -+{ -+ [_configuration.websiteDataStore _fetchDataRecordsOfTypes:dataTypes() withOptions:_WKWebsiteDataStoreFetchOptionComputeSizes completionHandler:^(NSArray *websiteDataRecords) { -+ NSLog(@"did fetch website data %@.", websiteDataRecords); -+ }]; -+} -+ -+- (IBAction)fetchAndClearWebsiteData:(id)sender -+{ -+ [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) { -+ [_configuration.websiteDataStore removeDataOfTypes:dataTypes() forDataRecords:websiteDataRecords completionHandler:^{ -+ [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) { -+ NSLog(@"did clear website data, after clearing data is %@.", websiteDataRecords); -+ }]; -+ }]; -+ }]; -+} -+ -+- (IBAction)clearWebsiteData:(id)sender -+{ -+ [_configuration.websiteDataStore removeDataOfTypes:dataTypes() modifiedSince:[NSDate distantPast] completionHandler:^{ -+ NSLog(@"Did clear website data."); -+ }]; -+} -+ -+- (IBAction)printWebView:(id)sender -+{ -+ [[_webView printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil]; -+} -+ -+#pragma mark WKNavigationDelegate -+ -+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler -+{ -+ LOG(@"decidePolicyForNavigationAction"); -+ -+ if (navigationAction._canHandleRequest) { -+ decisionHandler(WKNavigationActionPolicyAllow); -+ return; -+ } -+ decisionHandler(WKNavigationActionPolicyCancel); -+} -+ -+- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler -+{ -+ if (![navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { -+ decisionHandler(WKNavigationResponsePolicyAllow); -+ return; -+ } -+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)navigationResponse.response; -+ -+ NSString *disposition = [[httpResponse allHeaderFields] objectForKey:@"Content-Disposition"]; -+ if (disposition && [disposition hasPrefix:@"attachment"]) { -+ decisionHandler(_WKNavigationResponsePolicyBecomeDownload); -+ return; -+ } -+ decisionHandler(WKNavigationResponsePolicyAllow); -+} -+ -+- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation -+{ -+ LOG(@"didStartProvisionalNavigation: %@", navigation); -+} -+ -+- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation -+{ -+ LOG(@"didReceiveServerRedirectForProvisionalNavigation: %@", navigation); -+} -+ -+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error -+{ -+ LOG(@"didFailProvisionalNavigation: %@navigation, error: %@", navigation, error); -+} -+ -+- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation -+{ -+ LOG(@"didCommitNavigation: %@", navigation); -+ [self updateTitle:nil]; -+} -+ -+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation -+{ -+ LOG(@"didFinishNavigation: %@", navigation); -+} -+ -+- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler -+{ -+ LOG(@"didReceiveAuthenticationChallenge: %@", challenge); -+ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) { -+ NSAlert *alert = [[NSAlert alloc] init]; -+ NSView *container = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, 48)] autorelease]; -+ NSTextField *userInput = [[[NSTextField alloc] initWithFrame:NSMakeRect(0, 24, 200, 24)] autorelease]; -+ NSTextField *passwordInput = [[[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)] autorelease]; -+ -+ [alert setMessageText:[NSString stringWithFormat:@"Log in to %@:%lu.", challenge.protectionSpace.host, challenge.protectionSpace.port]]; -+ [alert addButtonWithTitle:@"Log in"]; -+ [alert addButtonWithTitle:@"Cancel"]; -+ [container addSubview:userInput]; -+ [container addSubview:passwordInput]; -+ [alert setAccessoryView:container]; -+ [userInput setNextKeyView:passwordInput]; -+ [alert.window setInitialFirstResponder:userInput]; -+ -+ [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse response) { -+ [userInput validateEditing]; -+ if (response == NSAlertFirstButtonReturn) -+ completionHandler(NSURLSessionAuthChallengeUseCredential, [[[NSURLCredential alloc] initWithUser:[userInput stringValue] password:[passwordInput stringValue] persistence:NSURLCredentialPersistenceForSession] autorelease]); -+ else -+ completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); -+ [alert release]; -+ }]; -+ return; -+ } -+ completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); -+} -+ -+- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error -+{ -+ LOG(@"didFailNavigation: %@, error %@", navigation, error); -+} -+ -+- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView -+{ -+ NSLog(@"WebContent process crashed; reloading"); -+ [self reload:nil]; -+} -+ -+- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents -+{ -+ if (progressEvents & _WKRenderingProgressEventFirstLayout) -+ LOG(@"renderingProgressDidChange: %@", @"first layout"); -+ -+ if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout) -+ LOG(@"renderingProgressDidChange: %@", @"first visually non-empty layout"); -+ -+ if (progressEvents & _WKRenderingProgressEventFirstPaintWithSignificantArea) -+ LOG(@"renderingProgressDidChange: %@", @"first paint with significant area"); -+ -+ if (progressEvents & _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering) -+ LOG(@"renderingProgressDidChange: %@", @"first layout after suppressed incremental rendering"); -+ -+ if (progressEvents & _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering) -+ LOG(@"renderingProgressDidChange: %@", @"first paint after suppressed incremental rendering"); -+} -+ -+- (void)webView:(WKWebView *)webView shouldLoadIconWithParameters:(_WKLinkIconParameters *)parameters completionHandler:(void (^)(void (^)(NSData*)))completionHandler -+{ -+ completionHandler(^void (NSData *data) { -+ LOG(@"Icon URL %@ received icon data of length %u", parameters.url, (unsigned)data.length); -+ }); -+} -+ -+#pragma mark Find in Page -+ -+- (IBAction)performTextFinderAction:(id)sender -+{ -+ [_textFinder performAction:[sender tag]]; -+} -+ -+- (NSView *)findBarView -+{ -+ return _textFindBarView; -+} -+ -+- (void)setFindBarView:(NSView *)findBarView -+{ -+ _textFindBarView = findBarView; -+ _findBarVisible = YES; -+ [_textFindBarView setFrame:NSMakeRect(0, 0, containerView.bounds.size.width, _textFindBarView.frame.size.height)]; -+} -+ -+- (BOOL)isFindBarVisible -+{ -+ return _findBarVisible; -+} -+ -+- (void)setFindBarVisible:(BOOL)findBarVisible -+{ -+ _findBarVisible = findBarVisible; -+ if (findBarVisible) -+ [containerView addSubview:_textFindBarView]; -+ else -+ [_textFindBarView removeFromSuperview]; -+} -+ -+- (NSView *)contentView -+{ -+ return _webView; -+} -+ -+- (void)findBarViewDidChangeHeight -+{ -+} -+ -+- (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL authorized))decisionHandler -+{ -+ decisionHandler(true); -+} -+ -+- (void)_webView:(WKWebView *)webView includeSensitiveMediaDeviceDetails:(void (^)(BOOL includeSensitiveDetails))decisionHandler -+{ -+ decisionHandler(false); -+} -+ -+- (IBAction)saveAsPDF:(id)sender -+{ -+ NSSavePanel *panel = [NSSavePanel savePanel]; -+ panel.allowedFileTypes = @[ @"pdf" ]; -+ [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { -+ if (result == NSModalResponseOK) { -+ [_webView createPDFWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) { -+ [pdfSnapshotData writeToURL:[panel URL] options:0 error:nil]; -+ }]; -+ } -+ }]; -+} -+ -+- (IBAction)saveAsWebArchive:(id)sender -+{ -+ NSSavePanel *panel = [NSSavePanel savePanel]; -+ panel.allowedFileTypes = @[ @"webarchive" ]; -+ [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { -+ if (result == NSModalResponseOK) { -+ [_webView createWebArchiveDataWithCompletionHandler:^(NSData *archiveData, NSError *error) { -+ [archiveData writeToURL:[panel URL] options:0 error:nil]; -+ }]; -+ } -+ }]; -+} -+ -+- (WKWebView *)webView -+{ -+ return _webView; -+} -+ -+@end -diff --git a/Tools/Playwright/mac/CMakeLists.txt b/Tools/Playwright/mac/CMakeLists.txt -new file mode 100644 -index 0000000000000000000000000000000000000000..410d47425b79367114b17274355350894a70a5e6 ---- /dev/null -+++ b/Tools/Playwright/mac/CMakeLists.txt -@@ -0,0 +1,43 @@ -+set(PLAYWRIGHT_DIR "${TOOLS_DIR}/Playwright/mac") -+ -+#FIXME: This should not need WEBCORE_EXPORT defined. This means we are including WebCore headers, and we should not. -+add_definitions("-include Playwright_Prefix.pch -DWEBCORE_EXPORT=") -+ -+set(Playwright_SOURCES -+ ${PLAYWRIGHT_DIR}/AppDelegate.m -+ ${PLAYWRIGHT_DIR}/BrowserWindowController.m -+ ${PLAYWRIGHT_DIR}/main.m -+ ${TOOLS_DIR}/Playwright/MBToolbarItem.m -+) -+ -+set(Playwright_INCLUDE_DIRECTORIES -+ ${CMAKE_SOURCE_DIR}/Source -+ ${FORWARDING_HEADERS_DIR} -+ ${PLAYWRIGHT_DIR} -+) -+ -+set(Playwright_LIBRARIES -+ WebKit -+) -+ -+set(CMAKE_EXE_LINKER_FLAGS "-framework Cocoa") -+ -+set(EXECUTABLE_NAME Playwright) -+set(PRODUCT_NAME Playwright) -+ -+set(Playwright_Contents_Directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Playwright.app/Contents) -+make_directory(${Playwright_Contents_Directory}/Resources) -+add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib -+ COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib ${PLAYWRIGHT_DIR}/BrowserWindow.xib VERBATIM) -+add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/MainMenu.nib -+ COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/MainMenu.nib ${PLAYWRIGHT_DIR}/MainMenu.xib VERBATIM) -+add_custom_target(PlaywrightNibs ALL DEPENDS -+ ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib -+ ${Playwright_Contents_Directory}/Resources/MainMenu.nib -+) -+ -+include_directories(${Playwright_INCLUDE_DIRECTORIES}) -+add_executable(Playwright MACOSX_BUNDLE ${Playwright_SOURCES}) -+set_target_properties(Playwright PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PLAYWRIGHT_DIR}/Info.plist) -+target_link_libraries(Playwright ${Playwright_LIBRARIES}) -+add_dependencies(Playwright PlaywrightNibs) -diff --git a/Tools/Playwright/mac/Info.plist b/Tools/Playwright/mac/Info.plist -new file mode 100644 -index 0000000000000000000000000000000000000000..4ed50c40f2f0dfd0ddf7c546b3451ab426c0501e ---- /dev/null -+++ b/Tools/Playwright/mac/Info.plist -@@ -0,0 +1,56 @@ -+ -+ -+ -+ -+ CFBundleDevelopmentRegion -+ English -+ CFBundleExecutable -+ ${EXECUTABLE_NAME} -+ CFBundleIconFile -+ WebKit Browser -+ CFBundleIdentifier -+ ${PRODUCT_BUNDLE_IDENTIFIER} -+ CFBundleInfoDictionaryVersion -+ 6.0 -+ CFBundleName -+ ${PRODUCT_NAME} -+ CFBundlePackageType -+ APPL -+ CFBundleSignature -+ ???? -+ CFBundleShortVersionString -+ 1.0 -+ LSMinimumSystemVersion -+ ${MACOSX_DEPLOYMENT_TARGET} -+ CFBundleVersion -+ 1 -+ NSMainNibFile -+ MainMenu -+ NSPrincipalClass -+ NSApplication -+ NSAppTransportSecurity -+ -+ NSAllowsArbitraryLoads -+ -+ -+ NSSupportsAutomaticGraphicsSwitching -+ -+ CFBundleDocumentTypes -+ -+ -+ CFBundleTypeExtensions -+ -+ html -+ -+ CFBundleTypeMIMETypes -+ -+ text/html -+ -+ CFBundleTypeName -+ HTML -+ CFBundleTypeRole -+ Editor -+ -+ -+ -+ -diff --git a/Tools/Playwright/mac/MainMenu.xib b/Tools/Playwright/mac/MainMenu.xib -new file mode 100644 -index 0000000000000000000000000000000000000000..b16d639a1ad18354e058c613987d846acd70b361 ---- /dev/null -+++ b/Tools/Playwright/mac/MainMenu.xib -@@ -0,0 +1,333 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/Tools/Playwright/mac/Playwright_Prefix.pch b/Tools/Playwright/mac/Playwright_Prefix.pch -new file mode 100644 -index 0000000000000000000000000000000000000000..ab6e9bce9a41291bb35664c2c63751c3413601f2 ---- /dev/null -+++ b/Tools/Playwright/mac/Playwright_Prefix.pch -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (C) 2010 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. -+ */ -+ -+#ifdef __OBJC__ -+#import -+#import -+#endif -+ -+#define ENABLE_LOGGING 0 -+ -+#if ENABLE_LOGGING -+#define LOG NSLog -+#else -+#define LOG(...) ((void)0) -+#endif -diff --git a/Tools/Playwright/mac/main.m b/Tools/Playwright/mac/main.m -new file mode 100644 -index 0000000000000000000000000000000000000000..ba2ca12482c0ab809998131f693c876019c595f1 ---- /dev/null -+++ b/Tools/Playwright/mac/main.m -@@ -0,0 +1,33 @@ -+/* -+ * Copyright (C) 2010 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 -+ -+int main(int argc, char *argv[]) -+{ -+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitLinkedOnOrAfterEverything"]; -+ -+ return NSApplicationMain(argc, (const char **) argv); -+} -diff --git a/Tools/Playwright/win/CMakeLists.txt b/Tools/Playwright/win/CMakeLists.txt -new file mode 100644 -index 0000000000000000000000000000000000000000..b8076d8a4caa71c078499e03220fbd3b5ca77f3f ---- /dev/null -+++ b/Tools/Playwright/win/CMakeLists.txt -@@ -0,0 +1,42 @@ -+set(Playwright_INCLUDE_DIRECTORIES -+ ${PAL_FRAMEWORK_HEADERS_DIR} -+ ${WebCore_PRIVATE_FRAMEWORK_HEADERS_DIR} -+ ${WebKit_FRAMEWORK_HEADERS_DIR} -+ ${WebKit_PRIVATE_FRAMEWORK_HEADERS_DIR} -+) -+ -+set(Playwright_SOURCES -+ Common.cpp -+ MainWindow.cpp -+ PlaywrightLib.rc -+ WebKitBrowserWindow.cpp -+ WinMain.cpp -+ stdafx.cpp -+) -+ -+set(Playwright_LIBRARIES -+ DbgHelp -+ WebKit::WTF -+ comctl32 -+ comsupp -+ comsuppw -+ shlwapi -+ WebKit -+) -+ -+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MSVC_RUNTIME_LINKER_FLAGS}") -+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wWinMainCRTStartup") -+ -+if (${WTF_PLATFORM_WIN_CAIRO}) -+ add_definitions(-DWIN_CAIRO) -+endif () -+add_definitions(-D_UNICODE) -+include_directories(${Playwright_INCLUDE_DIRECTORIES}) -+add_library(PlaywrightLib SHARED ${Playwright_SOURCES}) -+target_link_libraries(PlaywrightLib ${Playwright_LIBRARIES}) -+ -+add_executable(Playwright WIN32 ${TOOLS_DIR}/win/DLLLauncher/DLLLauncherMain.cpp Playwright.rc) -+target_link_libraries(Playwright shlwapi) -+set_target_properties(Playwright PROPERTIES OUTPUT_NAME "Playwright") -+ -+add_dependencies(Playwright PlaywrightLib) -diff --git a/Tools/Playwright/win/Common.cpp b/Tools/Playwright/win/Common.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..969425bec9f9fc0bef0330224b9e6d6b853222e5 ---- /dev/null -+++ b/Tools/Playwright/win/Common.cpp -@@ -0,0 +1,349 @@ -+/* -+ * Copyright (C) 2006, 2008, 2013-2015 Apple Inc. All rights reserved. -+ * Copyright (C) 2009, 2011 Brent Fulgham. All rights reserved. -+ * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved. -+ * Copyright (C) 2013 Alex Christensen. 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. ``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 -+ * 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 "stdafx.h" -+#include "Common.h" -+ -+#include "DialogHelper.h" -+#include "PlaywrightLibResource.h" -+#include "PlaywrightReplace.h" -+#include -+#include -+#include -+#include -+#include -+ -+// Global Variables: -+HINSTANCE hInst; -+ -+// Support moving the transparent window -+POINT s_windowPosition = { 100, 100 }; -+SIZE s_windowSize = { 500, 200 }; -+ -+namespace WebCore { -+float deviceScaleFactorForWindow(HWND); -+} -+ -+void computeFullDesktopFrame() -+{ -+ RECT desktop; -+ if (!::SystemParametersInfo(SPI_GETWORKAREA, 0, static_cast(&desktop), 0)) -+ return; -+ -+ float scaleFactor = WebCore::deviceScaleFactorForWindow(nullptr); -+ -+ s_windowPosition.x = 0; -+ s_windowPosition.y = 0; -+ s_windowSize.cx = scaleFactor * (desktop.right - desktop.left); -+ s_windowSize.cy = scaleFactor * (desktop.bottom - desktop.top); -+} -+ -+BOOL WINAPI DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID) -+{ -+ if (reason == DLL_PROCESS_ATTACH) -+ hInst = dllInstance; -+ -+ return TRUE; -+} -+ -+bool getAppDataFolder(_bstr_t& directory) -+{ -+ wchar_t appDataDirectory[MAX_PATH]; -+ if (FAILED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, appDataDirectory))) -+ return false; -+ -+ wchar_t executablePath[MAX_PATH]; -+ if (!::GetModuleFileNameW(0, executablePath, MAX_PATH)) -+ return false; -+ -+ ::PathRemoveExtensionW(executablePath); -+ -+ directory = _bstr_t(appDataDirectory) + L"\\" + ::PathFindFileNameW(executablePath); -+ -+ return true; -+} -+ -+void createCrashReport(EXCEPTION_POINTERS* exceptionPointers) -+{ -+ _bstr_t directory; -+ -+ if (!getAppDataFolder(directory)) -+ return; -+ -+ if (::SHCreateDirectoryEx(0, directory, 0) != ERROR_SUCCESS -+ && ::GetLastError() != ERROR_FILE_EXISTS -+ && ::GetLastError() != ERROR_ALREADY_EXISTS) -+ return; -+ -+ std::wstring fileName = std::wstring(static_cast(directory)) + L"\\CrashReport.dmp"; -+ HANDLE miniDumpFile = ::CreateFile(fileName.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); -+ -+ if (miniDumpFile && miniDumpFile != INVALID_HANDLE_VALUE) { -+ -+ MINIDUMP_EXCEPTION_INFORMATION mdei; -+ mdei.ThreadId = ::GetCurrentThreadId(); -+ mdei.ExceptionPointers = exceptionPointers; -+ mdei.ClientPointers = 0; -+ -+#ifdef _DEBUG -+ MINIDUMP_TYPE dumpType = MiniDumpWithFullMemory; -+#else -+ MINIDUMP_TYPE dumpType = MiniDumpNormal; -+#endif -+ -+ ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), miniDumpFile, dumpType, &mdei, 0, 0); -+ ::CloseHandle(miniDumpFile); -+ processCrashReport(fileName.c_str()); -+ } -+} -+ -+bool askProxySettings(HWND hwnd, ProxySettings& settings) -+{ -+ class ProxyDialog : public Dialog { -+ public: -+ ProxyDialog(ProxySettings& settings) -+ : settings { settings } -+ { -+ } -+ -+ protected: -+ ProxySettings& settings; -+ -+ void setup() final -+ { -+ auto command = commandForProxyChoice(); -+ proxyChoice().set(command); -+ setText(IDC_PROXY_URL, settings.url); -+ setText(IDC_PROXY_EXCLUDE, settings.excludeHosts); -+ } -+ -+ void ok() final -+ { -+ settings.url = getText(IDC_PROXY_URL); -+ settings.excludeHosts = getText(IDC_PROXY_EXCLUDE); -+ updateProxyChoice(proxyChoice().get()); -+ } -+ -+ bool validate() final -+ { -+ bool valid = true; -+ -+ if (proxyChoice().get() == IDC_PROXY_CUSTOM) { -+ setEnabled(IDC_PROXY_URL, true); -+ setEnabled(IDC_PROXY_EXCLUDE, true); -+ -+ if (!getTextLength(IDC_PROXY_URL)) -+ valid = false; -+ } else { -+ setEnabled(IDC_PROXY_URL, false); -+ setEnabled(IDC_PROXY_EXCLUDE, false); -+ } -+ -+ return valid; -+ } -+ -+ RadioGroup proxyChoice() -+ { -+ return radioGroup(IDC_PROXY_DEFAULT, IDC_PROXY_DISABLE); -+ } -+ -+ int commandForProxyChoice() -+ { -+ if (!settings.enable) -+ return IDC_PROXY_DISABLE; -+ if (settings.custom) -+ return IDC_PROXY_CUSTOM; -+ return IDC_PROXY_DEFAULT; -+ } -+ -+ void updateProxyChoice(int command) -+ { -+ switch (command) { -+ case IDC_PROXY_DEFAULT: -+ settings.enable = true; -+ settings.custom = false; -+ break; -+ case IDC_PROXY_CUSTOM: -+ settings.enable = true; -+ settings.custom = true; -+ break; -+ case IDC_PROXY_DISABLE: -+ settings.enable = false; -+ settings.custom = false; -+ break; -+ default: -+ break; -+ } -+ } -+ }; -+ -+ ProxyDialog dialog { settings }; -+ return dialog.run(hInst, hwnd, IDD_PROXY); -+} -+ -+Optional askCredential(HWND hwnd, const std::wstring& realm) -+{ -+ struct AuthDialog : public Dialog { -+ std::wstring realm; -+ Credential credential; -+ -+ protected: -+ void setup() -+ { -+ setText(IDC_REALM_TEXT, realm); -+ } -+ -+ void ok() final -+ { -+ credential.username = getText(IDC_AUTH_USER); -+ credential.password = getText(IDC_AUTH_PASSWORD); -+ } -+ }; -+ -+ AuthDialog dialog; -+ dialog.realm = realm; -+ -+ if (dialog.run(hInst, hwnd, IDD_AUTH)) -+ return dialog.credential; -+ return WTF::nullopt; -+} -+ -+bool askServerTrustEvaluation(HWND hwnd, const std::wstring& text) -+{ -+ class ServerTrustEvaluationDialog : public Dialog { -+ public: -+ ServerTrustEvaluationDialog(const std::wstring& text) -+ : m_text { text } -+ { -+ SendMessage(GetDlgItem(this->hDlg(), IDC_SERVER_TRUST_TEXT), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE); -+ } -+ -+ protected: -+ std::wstring m_text; -+ -+ void setup() -+ { -+ setText(IDC_SERVER_TRUST_TEXT, m_text); -+ } -+ -+ void ok() final -+ { -+ -+ } -+ }; -+ -+ ServerTrustEvaluationDialog dialog { text }; -+ return dialog.run(hInst, hwnd, IDD_SERVER_TRUST); -+} -+ -+CommandLineOptions parseCommandLine() -+{ -+ CommandLineOptions options; -+ -+ int argc = 0; -+ WCHAR** argv = CommandLineToArgvW(GetCommandLineW(), &argc); -+ for (int i = 1; i < argc; ++i) { -+ if (!wcsicmp(argv[i], L"--desktop")) -+ options.useFullDesktop = true; -+ else if (!wcsicmp(argv[i], L"--inspector-pipe")) -+ options.inspectorPipe = true; -+ else if (!wcsncmp(argv[i], L"--user-data-dir=", 16)) -+ options.userDataDir = argv[i] + 16; -+ else if (!wcsicmp(argv[i], L"--headless")) -+ options.headless = true; -+ else if (!wcsicmp(argv[i], L"--no-startup-window")) -+ options.noStartupWindow = true; -+ else if (!options.requestedURL) -+ options.requestedURL = argv[i]; -+ } -+ -+ return options; -+} -+ -+std::wstring replaceString(std::wstring src, const std::wstring& oldValue, const std::wstring& newValue) -+{ -+ if (src.empty() || oldValue.empty()) -+ return src; -+ -+ size_t pos = 0; -+ while ((pos = src.find(oldValue, pos)) != src.npos) { -+ src.replace(pos, oldValue.length(), newValue); -+ pos += newValue.length(); -+ } -+ -+ return src; -+} -+ -+std::wstring createString(WKStringRef wkString) -+{ -+ size_t maxSize = WKStringGetLength(wkString); -+ -+ std::vector wkCharBuffer(maxSize); -+ size_t actualLength = WKStringGetCharacters(wkString, wkCharBuffer.data(), maxSize); -+ return std::wstring(wkCharBuffer.data(), actualLength); -+} -+ -+std::wstring createString(WKURLRef wkURL) -+{ -+ if (!wkURL) -+ return { }; -+ WKRetainPtr url = adoptWK(WKURLCopyString(wkURL)); -+ return createString(url.get()); -+} -+ -+std::string createUTF8String(const wchar_t* src, size_t srcLength) -+{ -+ int length = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, 0, 0, nullptr, nullptr); -+ std::vector buffer(length); -+ size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr); -+ return { buffer.data(), actualLength }; -+} -+ -+WKRetainPtr createWKString(_bstr_t str) -+{ -+ auto utf8 = createUTF8String(str, str.length()); -+ return adoptWK(WKStringCreateWithUTF8CString(utf8.data())); -+} -+ -+WKRetainPtr createWKString(const std::wstring& str) -+{ -+ auto utf8 = createUTF8String(str.c_str(), str.length()); -+ return adoptWK(WKStringCreateWithUTF8CString(utf8.data())); -+} -+ -+WKRetainPtr createWKURL(_bstr_t str) -+{ -+ auto utf8 = createUTF8String(str, str.length()); -+ return adoptWK(WKURLCreateWithUTF8CString(utf8.data())); -+} -+ -+WKRetainPtr createWKURL(const std::wstring& str) -+{ -+ auto utf8 = createUTF8String(str.c_str(), str.length()); -+ return adoptWK(WKURLCreateWithUTF8CString(utf8.data())); -+} -diff --git a/Tools/Playwright/win/Common.h b/Tools/Playwright/win/Common.h -new file mode 100644 -index 0000000000000000000000000000000000000000..da9b00c96f9bc9c3c52e76a719650e8d604b1e0a ---- /dev/null -+++ b/Tools/Playwright/win/Common.h -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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. -+ */ -+ -+#pragma once -+ -+#include "stdafx.h" -+#include -+#include -+#include -+#include -+ -+struct CommandLineOptions { -+ bool useFullDesktop { }; -+ bool inspectorPipe { }; -+ bool headless { }; -+ bool noStartupWindow { }; -+ _bstr_t requestedURL; -+ _bstr_t userDataDir; -+ -+ CommandLineOptions() -+ { -+ } -+}; -+ -+struct Credential { -+ std::wstring username; -+ std::wstring password; -+}; -+ -+struct ProxySettings { -+ bool enable { true }; -+ bool custom { false }; -+ std::wstring url; -+ std::wstring excludeHosts; -+}; -+ -+void computeFullDesktopFrame(); -+bool getAppDataFolder(_bstr_t& directory); -+CommandLineOptions parseCommandLine(); -+void createCrashReport(EXCEPTION_POINTERS*); -+Optional askCredential(HWND, const std::wstring& realm); -+bool askProxySettings(HWND, ProxySettings&); -+ -+bool askServerTrustEvaluation(HWND, const std::wstring& text); -+std::wstring replaceString(std::wstring src, const std::wstring& oldValue, const std::wstring& newValue); -+ -+extern HINSTANCE hInst; -+extern POINT s_windowPosition; -+extern SIZE s_windowSize; -+ -+std::wstring createString(WKStringRef wkString); -+std::wstring createString(WKURLRef wkURL); -+std::string createUTF8String(const wchar_t* src, size_t srcLength); -+WKRetainPtr createWKString(_bstr_t str); -+WKRetainPtr createWKString(const std::wstring& str); -+WKRetainPtr createWKURL(_bstr_t str); -+WKRetainPtr createWKURL(const std::wstring& str); -diff --git a/Tools/Playwright/win/DialogHelper.h b/Tools/Playwright/win/DialogHelper.h -new file mode 100644 -index 0000000000000000000000000000000000000000..6590fe00255841fa93a0fe7c6bffbc0dc13fd2d0 ---- /dev/null -+++ b/Tools/Playwright/win/DialogHelper.h -@@ -0,0 +1,153 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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. -+ */ -+ -+#pragma once -+ -+#include "stdafx.h" -+#include -+#include -+ -+class Dialog { -+public: -+ bool run(HINSTANCE hInst, HWND hwnd, int dialogId) -+ { -+ auto result = DialogBoxParam(hInst, MAKEINTRESOURCE(dialogId), hwnd, doalogProc, reinterpret_cast(this)); -+ return (result > 0); -+ } -+ -+ static INT_PTR CALLBACK doalogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -+ { -+ if (message == WM_INITDIALOG) -+ SetWindowLongPtr(hDlg, DWLP_USER, lParam); -+ else -+ lParam = GetWindowLongPtr(hDlg, DWLP_USER); -+ -+ auto* dialog = reinterpret_cast(lParam); -+ return dialog->handle(hDlg, message, wParam); -+ } -+ -+protected: -+ INT_PTR handle(HWND hDlg, UINT message, WPARAM wParam) -+ { -+ switch (message) { -+ case WM_INITDIALOG: { -+ m_hDlg = hDlg; -+ setup(); -+ update(); -+ return TRUE; -+ } -+ case WM_COMMAND: -+ int wmId = LOWORD(wParam); -+ switch (wmId) { -+ case IDOK: -+ ok(); -+ close(true); -+ return TRUE; -+ case IDCANCEL: -+ cancel(); -+ close(false); -+ return TRUE; -+ default: -+ auto handled = command(wmId); -+ update(); -+ return handled; -+ } -+ } -+ return FALSE; -+ } -+ -+ virtual void setup() { } -+ virtual void update() { updateOkButton(validate()); } -+ virtual bool validate() { return true; } -+ virtual void updateOkButton(bool isValid) { setEnabled(IDOK, isValid); } -+ virtual bool command(int wmId) { return false; } -+ virtual void ok() { } -+ virtual void cancel() { } -+ -+ void close(bool success) { EndDialog(m_hDlg, success); } -+ -+ HWND hDlg() { return m_hDlg; } -+ -+ HWND item(int itemId) { return GetDlgItem(m_hDlg, itemId); } -+ -+ void setEnabled(int itemId, bool enabled) -+ { -+ EnableWindow(item(itemId), enabled); -+ } -+ -+ void setText(int itemId, const std::wstring& str) -+ { -+ SetDlgItemText(m_hDlg, itemId, _bstr_t(str.c_str())); -+ } -+ -+ std::wstring getText(int itemId) -+ { -+ auto length = getTextLength(itemId); -+ std::vector buffer(length + 1, 0); -+ GetWindowText(item(itemId), buffer.data(), length + 1); -+ return std::wstring { buffer.data() }; -+ } -+ -+ int getTextLength(int itemId) -+ { -+ return GetWindowTextLength(item(itemId)); -+ } -+ -+ class RadioGroup { -+ public: -+ RadioGroup(Dialog& dialog, int first, int last) -+ : m_dialog(dialog) -+ , m_first(first) -+ , m_last(last) -+ { -+ } -+ -+ void set(int item) -+ { -+ CheckRadioButton(m_dialog.hDlg(), m_first, m_last, item); -+ } -+ -+ int get() -+ { -+ for (int id = m_first; id <= m_last; id++) { -+ if (IsDlgButtonChecked(m_dialog.hDlg(), id) == BST_CHECKED) -+ return id; -+ } -+ return 0; -+ } -+ -+ private: -+ Dialog& m_dialog; -+ int m_first; -+ int m_last; -+ }; -+ -+ RadioGroup radioGroup(int first, int last) -+ { -+ return RadioGroup(*this, first, last); -+ } -+ -+ HWND m_hDlg { }; -+}; -diff --git a/Tools/Playwright/win/MainWindow.cpp b/Tools/Playwright/win/MainWindow.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..690c5e1d1fbef1f9420392b241a9f2c0247081c2 ---- /dev/null -+++ b/Tools/Playwright/win/MainWindow.cpp -@@ -0,0 +1,517 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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 "stdafx.h" -+#include "Common.h" -+#include "MainWindow.h" -+#include "PlaywrightLibResource.h" -+#include "WebKitBrowserWindow.h" -+#include -+ -+namespace WebCore { -+float deviceScaleFactorForWindow(HWND); -+} -+ -+static const wchar_t* kPlaywrightRegistryKey = L"Software\\WebKit\\Playwright"; -+ -+static constexpr int kToolbarImageSize = 32; -+static constexpr int kToolbarURLBarIndex = 4; -+static constexpr int kToolbarProgressIndicatorIndex = 5; -+ -+static WNDPROC DefEditProc = nullptr; -+ -+static LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM); -+static INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); -+ -+std::wstring MainWindow::s_windowClass; -+size_t MainWindow::s_numInstances; -+ -+bool MainWindow::s_headless = false; -+bool MainWindow::s_noStartupWindow = false; -+ -+void MainWindow::configure(bool headless, bool noStartupWindow) { -+ s_headless = headless; -+ s_noStartupWindow = noStartupWindow; -+} -+ -+static std::wstring loadString(int id) -+{ -+ constexpr size_t length = 100; -+ wchar_t buff[length]; -+ LoadString(hInst, id, buff, length); -+ return buff; -+} -+ -+void MainWindow::registerClass(HINSTANCE hInstance) -+{ -+ static bool initialized = false; -+ if (initialized) -+ return; -+ initialized = true; -+ -+ s_windowClass = loadString(IDC_PLAYWRIGHT); -+ -+ WNDCLASSEX wcex; -+ wcex.cbSize = sizeof(WNDCLASSEX); -+ wcex.style = CS_HREDRAW | CS_VREDRAW; -+ wcex.lpfnWndProc = WndProc; -+ wcex.cbClsExtra = 0; -+ wcex.cbWndExtra = 0; -+ wcex.hInstance = hInstance; -+ wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PLAYWRIGHT)); -+ wcex.hCursor = LoadCursor(0, IDC_ARROW); -+ wcex.hbrBackground = 0; -+ wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PLAYWRIGHT); -+ wcex.lpszClassName = s_windowClass.c_str(); -+ wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); -+ -+ RegisterClassEx(&wcex); -+} -+ -+bool MainWindow::isInstance(HWND hwnd) -+{ -+ wchar_t buff[64]; -+ if (!GetClassName(hwnd, buff, _countof(buff))) -+ return false; -+ return s_windowClass == buff; -+} -+ -+MainWindow::MainWindow() -+{ -+ s_numInstances++; -+} -+ -+MainWindow::~MainWindow() -+{ -+ s_numInstances--; -+} -+ -+void MainWindow::createToolbar(HINSTANCE hInstance) -+{ -+ m_hToolbarWnd = CreateWindowEx(0, TOOLBARCLASSNAME, nullptr, -+ WS_CHILD | WS_BORDER | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TOOLTIPS, 0, 0, 0, 0, -+ m_hMainWnd, nullptr, hInstance, nullptr); -+ -+ if (!m_hToolbarWnd) -+ return; -+ -+ const int ImageListID = 0; -+ const int numButtons = 4; -+ -+ HIMAGELIST hImageList; -+ hImageList = ImageList_LoadImage(hInstance, MAKEINTRESOURCE(IDB_TOOLBAR), kToolbarImageSize, 0, CLR_DEFAULT, IMAGE_BITMAP, 0); -+ -+ SendMessage(m_hToolbarWnd, TB_SETIMAGELIST, ImageListID, reinterpret_cast(hImageList)); -+ SendMessage(m_hToolbarWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_MIXEDBUTTONS); -+ -+ const DWORD buttonStyles = BTNS_AUTOSIZE; -+ -+ TBBUTTON tbButtons[] = { -+ { MAKELONG(0, ImageListID), IDM_HISTORY_BACKWARD, TBSTATE_ENABLED, buttonStyles | BTNS_DROPDOWN, { }, 0, (INT_PTR)L"Back" }, -+ { MAKELONG(1, ImageListID), IDM_HISTORY_FORWARD, TBSTATE_ENABLED, buttonStyles | BTNS_DROPDOWN, { }, 0, (INT_PTR)L"Forward"}, -+ { MAKELONG(2, ImageListID), IDM_RELOAD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Reload"}, -+ { MAKELONG(3, ImageListID), IDM_GO_HOME, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Home"}, -+ { 0, 0, TBSTATE_ENABLED, BTNS_SEP, { }, 0, 0}, // URL bar -+ { 0, 0, TBSTATE_ENABLED, BTNS_SEP, { }, 0, 0}, // Progress indicator -+ }; -+ ASSERT(tbButtons[kToolbarURLBarIndex].fsStyle == BTNS_SEP); -+ ASSERT(tbButtons[kToolbarProgressIndicatorIndex].fsStyle == BTNS_SEP); -+ -+ SendMessage(m_hToolbarWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); -+ SendMessage(m_hToolbarWnd, TB_ADDBUTTONS, _countof(tbButtons), reinterpret_cast(&tbButtons)); -+ ShowWindow(m_hToolbarWnd, true); -+ -+ m_hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0); -+ m_hProgressIndicator = CreateWindow(L"STATIC", 0, WS_CHILD | WS_VISIBLE | SS_CENTER | SS_CENTERIMAGE, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0); -+ -+ DefEditProc = reinterpret_cast(GetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC)); -+ SetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC, reinterpret_cast(EditProc)); -+} -+ -+void MainWindow::resizeToolbar(int parentWidth) -+{ -+ TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; -+ info.cx = parentWidth - m_toolbarItemsWidth; -+ SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast(&info)); -+ -+ SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); -+ -+ RECT rect; -+ SendMessage(m_hToolbarWnd, TB_GETITEMRECT, kToolbarURLBarIndex, reinterpret_cast(&rect)); -+ MoveWindow(m_hURLBarWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true); -+ -+ SendMessage(m_hToolbarWnd, TB_GETITEMRECT, kToolbarProgressIndicatorIndex, reinterpret_cast(&rect)); -+ MoveWindow(m_hProgressIndicator, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true); -+} -+ -+void MainWindow::rescaleToolbar() -+{ -+ const float scaleFactor = WebCore::deviceScaleFactorForWindow(m_hMainWnd); -+ const int scaledImageSize = kToolbarImageSize * scaleFactor; -+ -+ TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; -+ -+ info.cx = 0; -+ SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast(&info)); -+ info.cx = scaledImageSize * 2; -+ SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarProgressIndicatorIndex, reinterpret_cast(&info)); -+ -+ SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); -+ -+ int numItems = SendMessage(m_hToolbarWnd, TB_BUTTONCOUNT, 0, 0); -+ -+ RECT rect; -+ SendMessage(m_hToolbarWnd, TB_GETITEMRECT, numItems-1, reinterpret_cast(&rect)); -+ m_toolbarItemsWidth = rect.right; -+} -+ -+bool MainWindow::init(HINSTANCE hInstance, WKContextRef context, WKWebsiteDataStoreRef dataStore) -+{ -+ auto conf = adoptWK(WKPageConfigurationCreate()); -+ auto prefs = adoptWK(WKPreferencesCreate()); -+ -+ auto pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(createWKString("WinPlaywright").get())); -+ WKPageConfigurationSetPageGroup(conf.get(), pageGroup.get()); -+ WKPageGroupSetPreferences(pageGroup.get(), prefs.get()); -+ -+ WKPreferencesSetMediaCapabilitiesEnabled(prefs.get(), false); -+ WKPreferencesSetDeveloperExtrasEnabled(prefs.get(), true); -+ WKPageConfigurationSetPreferences(conf.get(), prefs.get()); -+ -+ WKPageConfigurationSetContext(conf.get(), context); -+ WKPageConfigurationSetWebsiteDataStore(conf.get(), dataStore); -+ -+ return init(hInstance, conf.get()); -+} -+ -+bool MainWindow::init(HINSTANCE hInstance, WKPageConfigurationRef conf) -+{ -+ m_configuration = conf; -+ -+ registerClass(hInstance); -+ -+ auto title = loadString(IDS_APP_TITLE); -+ -+ m_hMainWnd = CreateWindowExW(s_headless ? WS_EX_NOACTIVATE : 0, s_windowClass.c_str(), title.c_str(), -+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, this); -+ -+ if (!m_hMainWnd) -+ return false; -+ -+ if (!s_headless) { -+ createToolbar(hInstance); -+ if (!m_hToolbarWnd) -+ return false; -+ } -+ -+ m_browserWindow.reset(new WebKitBrowserWindow(*this, m_hMainWnd, conf)); -+ -+ updateDeviceScaleFactor(); -+ resizeSubViews(); -+ -+ if (s_headless) { -+ SetMenu(m_hMainWnd, NULL); -+ } else { -+ SetFocus(m_hURLBarWnd); -+ ShowWindow(m_hMainWnd, SW_SHOW); -+ } -+ return true; -+} -+ -+void MainWindow::resizeSubViews() -+{ -+ RECT rcClient; -+ GetClientRect(m_hMainWnd, &rcClient); -+ if (s_headless) { -+ MoveWindow(m_browserWindow->hwnd(), 0, 0, rcClient.right, rcClient.bottom, true); -+ return; -+ } -+ -+ resizeToolbar(rcClient.right); -+ -+ RECT rect; -+ GetWindowRect(m_hToolbarWnd, &rect); -+ POINT toolbarBottom = { 0, rect.bottom }; -+ ScreenToClient(m_hMainWnd, &toolbarBottom); -+ auto height = toolbarBottom.y; -+ MoveWindow(m_browserWindow->hwnd(), 0, height, rcClient.right, rcClient.bottom - height, true); -+} -+ -+LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -+{ -+ LRESULT result = 0; -+ MainWindow* thisWindow = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); -+ if (!thisWindow && message != WM_CREATE) -+ return DefWindowProc(hWnd, message, wParam, lParam); -+ -+ switch (message) { -+ case WM_ACTIVATE: -+ switch (LOWORD(wParam)) { -+ case WA_ACTIVE: -+ case WA_CLICKACTIVE: -+ SetFocus(thisWindow->browserWindow()->hwnd()); -+ } -+ break; -+ case WM_CREATE: -+ SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams)); -+ break; -+ case WM_APPCOMMAND: { -+ auto cmd = GET_APPCOMMAND_LPARAM(lParam); -+ switch (cmd) { -+ case APPCOMMAND_BROWSER_BACKWARD: -+ thisWindow->browserWindow()->navigateForwardOrBackward(false); -+ result = 1; -+ break; -+ case APPCOMMAND_BROWSER_FORWARD: -+ thisWindow->browserWindow()->navigateForwardOrBackward(true); -+ result = 1; -+ break; -+ case APPCOMMAND_BROWSER_HOME: -+ thisWindow->goHome(); -+ break; -+ case APPCOMMAND_BROWSER_REFRESH: -+ thisWindow->browserWindow()->reload(); -+ result = 1; -+ break; -+ case APPCOMMAND_BROWSER_STOP: -+ break; -+ } -+ break; -+ } -+ case WM_COMMAND: { -+ int wmId = LOWORD(wParam); -+ int wmEvent = HIWORD(wParam); -+ switch (wmEvent) { -+ case 0: // Menu or BN_CLICKED -+ case 1: // Accelerator -+ break; -+ default: -+ return DefWindowProc(hWnd, message, wParam, lParam); -+ } -+ // Parse the menu selections: -+ switch (wmId) { -+ case IDC_URL_BAR: -+ thisWindow->onURLBarEnter(); -+ break; -+ case IDM_NEW_WEBKIT_WINDOW: { -+ auto* newWindow = new MainWindow(); -+ newWindow->init(hInst, thisWindow->m_configuration.get()); -+ break; -+ } -+ case IDM_CLOSE_WINDOW: -+ PostMessage(hWnd, WM_CLOSE, 0, 0); -+ break; -+ case IDM_ABOUT: -+ DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); -+ break; -+ case IDM_GO_HOME: -+ thisWindow->goHome(); -+ break; -+ case IDM_EXIT: -+ DestroyWindow(hWnd); -+ break; -+ case IDM_WEB_INSPECTOR: -+ thisWindow->browserWindow()->launchInspector(); -+ break; -+ case IDM_HISTORY_BACKWARD: -+ case IDM_HISTORY_FORWARD: -+ thisWindow->browserWindow()->navigateForwardOrBackward(wmId == IDM_HISTORY_FORWARD); -+ break; -+ case IDM_ACTUAL_SIZE: -+ thisWindow->browserWindow()->resetZoom(); -+ break; -+ case IDM_RELOAD: -+ thisWindow->browserWindow()->reload(); -+ break; -+ case IDM_ZOOM_IN: -+ thisWindow->browserWindow()->zoomIn(); -+ break; -+ case IDM_ZOOM_OUT: -+ thisWindow->browserWindow()->zoomOut(); -+ break; -+ default: -+ if (!thisWindow->toggleMenuItem(wmId)) -+ return DefWindowProc(hWnd, message, wParam, lParam); -+ } -+ } -+ break; -+ case WM_DESTROY: -+ SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); -+ delete thisWindow; -+ if (s_noStartupWindow || s_numInstances > 1) -+ return 0; -+ PostQuitMessage(0); -+ break; -+ case WM_SIZE: -+ thisWindow->resizeSubViews(); -+ break; -+ case WM_DPICHANGED: { -+ thisWindow->updateDeviceScaleFactor(); -+ auto& rect = *reinterpret_cast(lParam); -+ SetWindowPos(hWnd, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE); -+ break; -+ } -+ default: -+ return DefWindowProc(hWnd, message, wParam, lParam); -+ } -+ -+ return result; -+} -+ -+static bool menuItemIsChecked(const MENUITEMINFO& info) -+{ -+ return info.fState & MFS_CHECKED; -+} -+ -+bool MainWindow::toggleMenuItem(UINT menuID) -+{ -+ if (s_headless) -+ return (INT_PTR)FALSE; -+ -+ HMENU menu = ::GetMenu(hwnd()); -+ -+ MENUITEMINFO info = { }; -+ info.cbSize = sizeof(info); -+ info.fMask = MIIM_STATE; -+ -+ if (!::GetMenuItemInfo(menu, menuID, FALSE, &info)) -+ return false; -+ -+ BOOL newState = !menuItemIsChecked(info); -+ info.fState = (newState) ? MFS_CHECKED : MFS_UNCHECKED; -+ ::SetMenuItemInfo(menu, menuID, FALSE, &info); -+ -+ return true; -+} -+ -+LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -+{ -+ switch (message) { -+ case WM_SETFOCUS: -+ PostMessage(hWnd, EM_SETSEL, 0, -1); -+ break; -+ case WM_CHAR: -+ if (wParam == 13) { -+ // Enter Key -+ ::PostMessage(GetParent(hWnd), static_cast(WM_COMMAND), MAKELPARAM(IDC_URL_BAR, 0), 0); -+ return 0; -+ } -+ break; -+ } -+ return CallWindowProc(DefEditProc, hWnd, message, wParam, lParam); -+} -+ -+// Message handler for about box. -+INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -+{ -+ UNREFERENCED_PARAMETER(lParam); -+ switch (message) { -+ case WM_INITDIALOG: -+ return (INT_PTR)TRUE; -+ -+ case WM_COMMAND: -+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { -+ EndDialog(hDlg, LOWORD(wParam)); -+ return (INT_PTR)TRUE; -+ } -+ break; -+ } -+ return (INT_PTR)FALSE; -+} -+ -+void MainWindow::loadURL(std::wstring url) -+{ -+ if (::PathFileExists(url.c_str()) || ::PathIsUNC(url.c_str())) { -+ wchar_t fileURL[INTERNET_MAX_URL_LENGTH]; -+ DWORD fileURLLength = _countof(fileURL); -+ -+ if (SUCCEEDED(::UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0))) -+ url = fileURL; -+ } -+ if (url.find(L"://") == url.npos && url.find(L"about:blank") == url.npos) -+ url = L"http://" + url; -+ -+ if (FAILED(m_browserWindow->loadURL(_bstr_t(url.c_str())))) -+ return; -+ -+ if (!s_headless) -+ SetFocus(m_browserWindow->hwnd()); -+} -+ -+void MainWindow::goHome() -+{ -+ std::wstring defaultURL = L"about:blank"; -+ loadURL(defaultURL); -+} -+ -+void MainWindow::onURLBarEnter() -+{ -+ if (s_headless) -+ return; -+ wchar_t url[INTERNET_MAX_URL_LENGTH]; -+ GetWindowText(m_hURLBarWnd, url, INTERNET_MAX_URL_LENGTH); -+ loadURL(url); -+} -+ -+void MainWindow::updateDeviceScaleFactor() -+{ -+ if (s_headless) -+ return; -+ if (m_hURLBarFont) -+ ::DeleteObject(m_hURLBarFont); -+ -+ rescaleToolbar(); -+ -+ RECT rect; -+ GetClientRect(m_hToolbarWnd, &rect); -+ int fontHeight = rect.bottom * 3. / 4; -+ -+ m_hURLBarFont = ::CreateFont(fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, -+ OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FF_DONTCARE, L"Tahoma"); -+ ::SendMessage(m_hURLBarWnd, static_cast(WM_SETFONT), reinterpret_cast(m_hURLBarFont), TRUE); -+} -+ -+void MainWindow::progressChanged(double progress) -+{ -+ if (s_headless) -+ return; -+ std::wostringstream text; -+ text << static_cast(progress * 100) << L'%'; -+ SetWindowText(m_hProgressIndicator, text.str().c_str()); -+} -+ -+void MainWindow::progressFinished() -+{ -+ if (s_headless) -+ return; -+ SetWindowText(m_hProgressIndicator, L""); -+} -+ -+void MainWindow::activeURLChanged(std::wstring url) -+{ -+ if (s_headless) -+ return; -+ SetWindowText(m_hURLBarWnd, url.c_str()); -+} -diff --git a/Tools/Playwright/win/MainWindow.h b/Tools/Playwright/win/MainWindow.h -new file mode 100644 -index 0000000000000000000000000000000000000000..b173f44a96dee7f0b80c8689b007754920fc64a3 ---- /dev/null -+++ b/Tools/Playwright/win/MainWindow.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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. -+ */ -+ -+#pragma once -+ -+#include "WebKitBrowserWindow.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+class MainWindow : public BrowserWindowClient { -+public: -+ static void configure(bool headless, bool noStartupWindow); -+ -+ MainWindow(); -+ -+ ~MainWindow(); -+ bool init(HINSTANCE hInstance, WKContextRef, WKWebsiteDataStoreRef); -+ bool init(HINSTANCE hInstance, WKPageConfigurationRef); -+ -+ void resizeSubViews(); -+ HWND hwnd() const { return m_hMainWnd; } -+ WebKitBrowserWindow* browserWindow() const { return m_browserWindow.get(); } -+ -+ void loadURL(std::wstring); -+ void goHome(); -+ -+ static bool isInstance(HWND); -+ -+private: -+ static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -+ static void registerClass(HINSTANCE hInstance); -+ static std::wstring s_windowClass; -+ static size_t s_numInstances; -+ static bool s_headless; -+ static bool s_noStartupWindow; -+ -+ bool toggleMenuItem(UINT menuID); -+ void onURLBarEnter(); -+ void updateDeviceScaleFactor(); -+ -+ void createToolbar(HINSTANCE); -+ void resizeToolbar(int); -+ void rescaleToolbar(); -+ -+ // BrowserWindowClient -+ void progressChanged(double) final; -+ void progressFinished() final; -+ void activeURLChanged(std::wstring) final; -+ -+ HWND m_hMainWnd { nullptr }; -+ HWND m_hToolbarWnd { nullptr }; -+ HWND m_hURLBarWnd { nullptr }; -+ HWND m_hProgressIndicator { nullptr }; -+ HWND m_hCacheWnd { nullptr }; -+ HGDIOBJ m_hURLBarFont { nullptr }; -+ // WKPageConfigurationRef retains page and WebKitBrowserWindow retains page via view -+ // make sure view is deleted after the page. -+ std::unique_ptr m_browserWindow; -+ WKRetainPtr m_configuration; -+ int m_toolbarItemsWidth { }; -+}; -diff --git a/Tools/Playwright/win/Playwright.ico b/Tools/Playwright/win/Playwright.ico -new file mode 100644 -index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 -Binary files /dev/null and b/Tools/Playwright/win/Playwright.ico differ -diff --git a/Tools/Playwright/win/Playwright.rc b/Tools/Playwright/win/Playwright.rc -new file mode 100644 -index 0000000000000000000000000000000000000000..4430f19062cc9fd048e4b1d5d8d33c5a119a8409 ---- /dev/null -+++ b/Tools/Playwright/win/Playwright.rc -@@ -0,0 +1,76 @@ -+// Microsoft Visual C++ generated resource script. -+// -+#include "PlaywrightResource.h" -+ -+#define APSTUDIO_READONLY_SYMBOLS -+///////////////////////////////////////////////////////////////////////////// -+// -+// Generated from the TEXTINCLUDE 2 resource. -+// -+#define APSTUDIO_HIDDEN_SYMBOLS -+#include "windows.h" -+#undef APSTUDIO_HIDDEN_SYMBOLS -+ -+///////////////////////////////////////////////////////////////////////////// -+#undef APSTUDIO_READONLY_SYMBOLS -+ -+///////////////////////////////////////////////////////////////////////////// -+// English (U.S.) resources -+ -+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -+#ifdef _WIN32 -+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -+#pragma code_page(1252) -+#endif //_WIN32 -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Icon -+// -+ -+// Icon with lowest ID value placed first to ensure application icon -+// remains consistent on all systems. -+IDI_PLAYWRIGHT ICON "Playwright.ico" -+ -+#ifdef APSTUDIO_INVOKED -+///////////////////////////////////////////////////////////////////////////// -+// -+// TEXTINCLUDE -+// -+ -+1 TEXTINCLUDE -+BEGIN -+ "PlaywrightResource.\0" -+END -+ -+2 TEXTINCLUDE -+BEGIN -+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" -+ "#include ""windows.h""\r\n" -+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" -+ "\0" -+END -+ -+3 TEXTINCLUDE -+BEGIN -+ "\r\n" -+ "\0" -+END -+ -+#endif // APSTUDIO_INVOKED -+ -+#endif // English (U.S.) resources -+///////////////////////////////////////////////////////////////////////////// -+ -+ -+ -+#ifndef APSTUDIO_INVOKED -+///////////////////////////////////////////////////////////////////////////// -+// -+// Generated from the TEXTINCLUDE 3 resource. -+// -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+#endif // not APSTUDIO_INVOKED -+ -diff --git a/Tools/Playwright/win/PlaywrightLib.rc b/Tools/Playwright/win/PlaywrightLib.rc -new file mode 100644 -index 0000000000000000000000000000000000000000..24192b98bdd5b55e94a7fd33c13d8301ee4ddc42 ---- /dev/null -+++ b/Tools/Playwright/win/PlaywrightLib.rc -@@ -0,0 +1,358 @@ -+// Microsoft Visual C++ generated resource script. -+// -+#include "PlaywrightLibResource.h" -+ -+#define APSTUDIO_READONLY_SYMBOLS -+///////////////////////////////////////////////////////////////////////////// -+// -+// Generated from the TEXTINCLUDE 2 resource. -+// -+#define APSTUDIO_HIDDEN_SYMBOLS -+#include "windows.h" -+#undef APSTUDIO_HIDDEN_SYMBOLS -+ -+///////////////////////////////////////////////////////////////////////////// -+#undef APSTUDIO_READONLY_SYMBOLS -+ -+///////////////////////////////////////////////////////////////////////////// -+// English (United States) resources -+ -+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -+#pragma code_page(1252) -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Icon -+// -+ -+// Icon with lowest ID value placed first to ensure application icon -+// remains consistent on all systems. -+IDI_PLAYWRIGHT ICON "Playwright.ico" -+ -+IDI_SMALL ICON "small.ico" -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Menu -+// -+ -+IDC_PLAYWRIGHT MENU -+BEGIN -+ POPUP "&File" -+ BEGIN -+ MENUITEM "E&xit", IDM_EXIT -+ MENUITEM "New WebKit Window", IDM_NEW_WEBKIT_WINDOW -+ MENUITEM "Close\tCtrl-W", IDM_CLOSE_WINDOW -+ END -+ POPUP "&View" -+ BEGIN -+ MENUITEM "Reload\tCtrl-R", IDM_RELOAD -+ MENUITEM "Actual Size\tCtrl+0", IDM_ACTUAL_SIZE -+ MENUITEM "Zoom In\tCtrl++", IDM_ZOOM_IN -+ MENUITEM "Zoom Out\tCtrl+-", IDM_ZOOM_OUT -+ MENUITEM "Invert Colors", IDM_INVERT_COLORS -+ MENUITEM "Go Home", IDM_GO_HOME -+ END -+ POPUP "&History" -+ BEGIN -+ MENUITEM "Back", IDM_HISTORY_BACKWARD -+ MENUITEM "Forward", IDM_HISTORY_FORWARD -+ END -+ POPUP "D&evelop" -+ BEGIN -+ MENUITEM "Show Web Inspector", IDM_WEB_INSPECTOR -+ END -+ POPUP "&Help" -+ BEGIN -+ MENUITEM "&About ...", IDM_ABOUT -+ END -+END -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Accelerator -+// -+ -+IDC_PLAYWRIGHT ACCELERATORS -+BEGIN -+ "/", IDM_ABOUT, ASCII, ALT, NOINVERT -+ "0", IDM_ACTUAL_SIZE, VIRTKEY, CONTROL, NOINVERT -+ "?", IDM_ABOUT, ASCII, ALT, NOINVERT -+ "R", IDM_RELOAD, VIRTKEY, CONTROL, NOINVERT -+ VK_ADD, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT -+ VK_OEM_MINUS, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT -+ VK_OEM_PLUS, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT -+ VK_SUBTRACT, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT -+END -+ -+IDR_ACCELERATORS_PRE ACCELERATORS -+BEGIN -+ "W", IDM_CLOSE_WINDOW, VIRTKEY, CONTROL, NOINVERT -+END -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Dialog -+// -+ -+IDD_ABOUTBOX DIALOGEX 22, 17, 230, 41 -+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -+CAPTION "About" -+FONT 8, "MS Shell Dlg", 0, 0, 0x0 -+BEGIN -+ ICON IDI_PLAYWRIGHT,IDC_MYICON,14,9,20,20 -+ LTEXT "Playwright Version 1.1",IDC_STATIC,49,10,119,8 -+ LTEXT "Copyright (C) 2015-2019",IDC_STATIC,49,20,119,8 -+ DEFPUSHBUTTON "OK",IDOK,186,10,30,11,WS_GROUP -+END -+ -+IDD_CACHES DIALOGEX 0, 0, 401, 456 -+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -+CAPTION "Dialog" -+FONT 8, "MS Shell Dlg", 400, 0, 0x1 -+BEGIN -+ DEFPUSHBUTTON "OK",IDOK,287,435,50,14 -+ PUSHBUTTON "Cancel",IDCANCEL,344,435,50,14 -+ GROUPBOX "FastMalloc",IDC_STATIC,208,14,186,67 -+ GROUPBOX "WebCore Cache",IDC_STATIC,17,83,376,105 -+ GROUPBOX "JavaScript Heap",IDC_STATIC,18,193,376,168 -+ GROUPBOX "Site Icon Database",IDC_STATIC,18,366,142,65 -+ GROUPBOX "Font and Glyph Caches",IDC_STATIC,168,366,226,66 -+ GROUPBOX "CFURLCache",IDC_STATIC,7,14,197,67 -+ PUSHBUTTON "Empty URLCache",IDC_EMPTY_URL_CACHE,131,63,69,14,WS_DISABLED -+ PUSHBUTTON "Return Free Memory",IDC_RETURN_FREE_MEMORY,308,63,76,14,WS_DISABLED -+ PUSHBUTTON "Empty WebCore Cache",IDC_EMPTY_WEBCORE_CACHE,21,170,83,14,WS_DISABLED -+ CONTROL "Disable WebCore Cache",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,119,172,93,10 -+ PUSHBUTTON "Garbage Collect JavaScript Objects",IDC_GC_JSC,253,343,135,14,WS_DISABLED -+ RTEXT "Reserved VM",IDC_STATIC,212,26,67,9 -+ RTEXT "0",IDC_RESERVED_VM,290,26,94,8 -+ RTEXT "Committed VM",IDC_STATIC,211,39,67,8 -+ RTEXT "0",IDC_COMMITTED_VM,290,39,94,8 -+ RTEXT "Free List Bytes",IDC_STATIC,211,52,67,8 -+ RTEXT "0",IDC_FREE_LIST_BYTES,290,52,94,8 -+ RTEXT "Images",IDC_STATIC,37,106,24,8 -+ RTEXT "CSS",IDC_STATIC,47,116,14,8 -+ RTEXT "XSL",IDC_STATIC,49,126,12,8 -+ RTEXT "JavaScript",IDC_STATIC,27,135,34,8 -+ RTEXT "Total",IDC_STATIC,43,146,17,8 -+ LTEXT "Objects",IDC_STATIC,111,96,26,8 -+ LTEXT "Bytes",IDC_STATIC,175,96,19,8 -+ LTEXT "Live",IDC_STATIC,232,96,14,8 -+ LTEXT "Decoded",IDC_STATIC,284,96,29,8 -+ LTEXT "Purgeable",IDC_STATIC,351,96,33,8 -+ RTEXT "0",IDC_IMAGES_OBJECT_COUNT,100,106,32,8 -+ RTEXT "0",IDC_CSS_OBJECT_COUNT,100,116,32,8 -+ RTEXT "0",IDC_XSL_OBJECT_COUNT,100,126,32,8 -+ RTEXT "0",IDC_JSC_OBJECT_COUNT,100,135,32,8 -+ RTEXT "0",IDC_TOTAL_OBJECT_COUNT,100,146,32,8 -+ RTEXT "0",IDC_IMAGES_BYTES,162,106,32,8 -+ RTEXT "0",IDC_CSS_BYTES,162,116,32,8 -+ RTEXT "0",IDC_XSL_BYTES,162,126,32,8 -+ RTEXT "0",IDC_JSC_BYTES,162,135,32,8 -+ RTEXT "0",IDC_TOTAL_BYTES,162,146,32,8 -+ RTEXT "0",IDC_IMAGES_LIVE_COUNT,221,106,32,8 -+ RTEXT "0",IDC_CSS_LIVE_COUNT,221,116,32,8 -+ RTEXT "0",IDC_XSL_LIVE_COUNT,221,126,32,8 -+ RTEXT "0",IDC_JSC_LIVE_COUNT,221,135,32,8 -+ RTEXT "0",IDC_TOTAL_LIVE_COUNT,221,146,32,8 -+ RTEXT "0",IDC_IMAGES_DECODED_COUNT,284,106,32,8 -+ RTEXT "0",IDC_CSS_DECODED_COUNT,284,116,32,8 -+ RTEXT "0",IDC_XSL_DECODED_COUNT,284,126,32,8 -+ RTEXT "0",IDC_JSC_DECODED_COUNT,284,135,32,8 -+ RTEXT "0",IDC_TOTAL_DECODED,284,146,32,8 -+ RTEXT "0",IDC_IMAGES_PURGEABLE_COUNT,354,106,32,8 -+ RTEXT "0",IDC_CSS_PURGEABLE_COUNT,354,116,32,8 -+ RTEXT "0",IDC_XSL_PURGEABLE_COUNT,354,126,32,8 -+ RTEXT "0",IDC_JSC_PURGEABLE_COUNT,354,135,32,8 -+ RTEXT "0",IDC_TOTAL_PURGEABLE,354,146,32,8 -+ RTEXT "Total Objects",IDC_STATIC,63,207,44,8 -+ RTEXT "Global Objects",IDC_STATIC,56,217,51,8 -+ RTEXT "Protected Objects",IDC_STATIC,48,227,59,8 -+ RTEXT "0",IDC_TOTAL_JSC_HEAP_OBJECTS,127,207,56,8 -+ RTEXT "0",IDC_GLOBAL_JSC_HEAP_OBJECTS,127,217,56,8 -+ RTEXT "0",IDC_PROTECTED_JSC_HEAP_OBJECTS,127,227,56,8 -+ RTEXT "Size",IDC_STATIC56,223,207,14,8 -+ RTEXT "Free",IDC_STATIC57,222,217,16,8 -+ RTEXT "0",IDC_JSC_HEAP_SIZE,270,207,56,8 -+ RTEXT "0",IDC_JSC_HEAP_FREE,270,217,56,8 -+ PUSHBUTTON "Purge Inactive Font Data",IDC_BUTTON5,293,415,95,14,WS_DISABLED -+ LTEXT "Total Font Data Objects",IDC_STATIC,208,379,78,8 -+ LTEXT "Inactive Font Data Objects",IDC_STATIC,198,390,88,8 -+ LTEXT "Glyph Pages",IDC_STATIC,246,402,40,8 -+ RTEXT "0",IDC_TOTAL_FONT_OBJECTS,329,379,56,8 -+ RTEXT "0",IDC_INACTIVE_FONT_OBJECTS,329,390,56,8 -+ RTEXT "0",IDC_GLYPH_PAGES,329,402,56,8 -+ LTEXT "Page URL Mappings",IDC_STATIC,33,380,64,8 -+ LTEXT "Retained Page URLs",IDC_STATIC,31,390,66,8 -+ LTEXT "Site Icon Records",IDC_STATIC,40,400,57,8 -+ LTEXT "Site Icons with Data",IDC_STATIC,32,410,65,8 -+ RTEXT "0",IDC_PAGE_URL_MAPPINGS,101,380,52,8 -+ RTEXT "0",IDC_RETAINED_PAGE_URLS,101,390,52,8 -+ RTEXT "0",IDC_SITE_ICON_RECORDS,101,400,52,8 -+ RTEXT "0",IDC_SITE_ICONS_WITH_DATA,101,410,52,8 -+END -+ -+IDD_AUTH DIALOGEX 0, 0, 231, 119 -+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -+CAPTION "Authentication Required" -+FONT 8, "MS Shell Dlg", 400, 0, 0x1 -+BEGIN -+ DEFPUSHBUTTON "Sign In",IDOK,116,98,50,14 -+ PUSHBUTTON "Cancel",IDCANCEL,174,98,50,14 -+ LTEXT "Realm",IDC_REALM_TEXT,67,21,157,8 -+ RTEXT "User Name:",IDC_STATIC,7,41,57,8 -+ EDITTEXT IDC_AUTH_USER,67,39,157,14,ES_AUTOHSCROLL -+ RTEXT "Password:",IDC_STATIC,7,66,57,8 -+ EDITTEXT IDC_AUTH_PASSWORD,67,64,157,14,ES_PASSWORD | ES_AUTOHSCROLL -+END -+ -+IDD_PROXY DIALOGEX 0, 0, 310, 176 -+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -+CAPTION "Proxy Configuration" -+FONT 8, "MS Shell Dlg", 400, 0, 0x1 -+BEGIN -+ DEFPUSHBUTTON "OK",IDOK,199,155,50,14 -+ PUSHBUTTON "Cancel",IDCANCEL,253,155,50,14 -+ CONTROL "Use system default proxy configuration.",IDC_PROXY_DEFAULT, -+ "Button",BS_AUTORADIOBUTTON | WS_GROUP,22,15,226,10 -+ CONTROL "Use custom proxy configuration:",IDC_PROXY_CUSTOM, -+ "Button",BS_AUTORADIOBUTTON,22,33,226,10 -+ CONTROL "Don't use proxy.",IDC_PROXY_DISABLE,"Button",BS_AUTORADIOBUTTON,22,117,226,10 -+ EDITTEXT IDC_PROXY_URL,76,52,193,14,ES_AUTOHSCROLL -+ EDITTEXT IDC_PROXY_EXCLUDE,76,85,193,14,ES_AUTOHSCROLL -+ LTEXT "URL:",IDC_STATIC,30,55,43,8,0,WS_EX_RIGHT -+ LTEXT "Excude list:",IDC_STATIC,30,88,43,8,0,WS_EX_RIGHT -+ LTEXT "Example: http://192.168.0.2:8000",IDC_STATIC,80,68,194,8 -+ LTEXT "Comma separated hostnames.",IDC_STATIC,80,101,194,8 -+END -+ -+IDD_SERVER_TRUST DIALOGEX 0, 0, 319, 184 -+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -+CAPTION "Server Trust Evaluation Request" -+FONT 8, "MS Shell Dlg", 400, 0, 0x1 -+BEGIN -+ DEFPUSHBUTTON "Yes",IDOK,197,163,50,14 -+ PUSHBUTTON "No",IDCANCEL,262,163,50,14 -+ LTEXT "Certificate information",IDC_STATIC,7,7,294,17 -+ EDITTEXT IDC_SERVER_TRUST_TEXT,7,24,305,130,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP -+END -+ -+ -+#ifdef APSTUDIO_INVOKED -+///////////////////////////////////////////////////////////////////////////// -+// -+// TEXTINCLUDE -+// -+ -+1 TEXTINCLUDE -+BEGIN -+ "PlaywrightLibResource.h\0" -+END -+ -+2 TEXTINCLUDE -+BEGIN -+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" -+ "#include ""windows.h""\r\n" -+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" -+ "\0" -+END -+ -+3 TEXTINCLUDE -+BEGIN -+ "\r\n" -+ "\0" -+END -+ -+#endif // APSTUDIO_INVOKED -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// DESIGNINFO -+// -+ -+#ifdef APSTUDIO_INVOKED -+GUIDELINES DESIGNINFO -+BEGIN -+ IDD_ABOUTBOX, DIALOG -+ BEGIN -+ END -+ -+ IDD_CACHES, DIALOG -+ BEGIN -+ LEFTMARGIN, 7 -+ RIGHTMARGIN, 394 -+ TOPMARGIN, 7 -+ BOTTOMMARGIN, 449 -+ END -+ -+ IDD_AUTH, DIALOG -+ BEGIN -+ LEFTMARGIN, 7 -+ RIGHTMARGIN, 224 -+ VERTGUIDE, 64 -+ VERTGUIDE, 67 -+ TOPMARGIN, 7 -+ BOTTOMMARGIN, 92 -+ HORZGUIDE, 25 -+ HORZGUIDE, 50 -+ END -+ -+ IDD_PROXY, DIALOG -+ BEGIN -+ LEFTMARGIN, 7 -+ RIGHTMARGIN, 303 -+ VERTGUIDE, 22 -+ TOPMARGIN, 7 -+ BOTTOMMARGIN, 169 -+ END -+ -+ IDD_SERVER_TRUST, DIALOG -+ BEGIN -+ LEFTMARGIN, 7 -+ RIGHTMARGIN, 312 -+ TOPMARGIN, 7 -+ BOTTOMMARGIN, 177 -+ END -+END -+#endif // APSTUDIO_INVOKED -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// Bitmap -+// -+ -+IDB_TOOLBAR BITMAP "toolbar.bmp" -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+// -+// String Table -+// -+ -+STRINGTABLE -+BEGIN -+ IDS_APP_TITLE "Playwright" -+ IDC_PLAYWRIGHT "Playwright" -+END -+ -+#endif // English (United States) resources -+///////////////////////////////////////////////////////////////////////////// -+ -+ -+ -+#ifndef APSTUDIO_INVOKED -+///////////////////////////////////////////////////////////////////////////// -+// -+// Generated from the TEXTINCLUDE 3 resource. -+// -+ -+ -+///////////////////////////////////////////////////////////////////////////// -+#endif // not APSTUDIO_INVOKED -+ -diff --git a/Tools/Playwright/win/PlaywrightLibResource.h b/Tools/Playwright/win/PlaywrightLibResource.h -new file mode 100644 -index 0000000000000000000000000000000000000000..6b1409e2d95a9a64af763915871eea5fed579e78 ---- /dev/null -+++ b/Tools/Playwright/win/PlaywrightLibResource.h -@@ -0,0 +1,119 @@ -+//{{NO_DEPENDENCIES}} -+// Microsoft Visual C++ generated include file. -+// Used by PlaywrightLib.rc -+// -+#define IDC_MYICON 2 -+#define IDD_PLAYWRIGHT_DIALOG 102 -+#define IDS_APP_TITLE 103 -+#define IDD_ABOUTBOX 103 -+#define IDM_ABOUT 104 -+#define IDM_EXIT 105 -+#define IDI_PLAYWRIGHT 107 -+#define IDI_SMALL 108 -+#define IDC_PLAYWRIGHT 109 -+#define IDM_WEB_INSPECTOR 120 -+#define IDM_INVERT_COLORS 125 -+#define IDR_MAINFRAME 128 -+#define IDD_CACHES 129 -+#define IDM_HISTORY_BACKWARD 130 -+#define IDD_USER_AGENT 130 -+#define IDM_HISTORY_FORWARD 131 -+#define IDM_HISTORY_LINK0 150 -+#define IDM_HISTORY_LINK1 151 -+#define IDM_HISTORY_LINK2 152 -+#define IDM_HISTORY_LINK3 153 -+#define IDM_HISTORY_LINK4 154 -+#define IDM_HISTORY_LINK5 155 -+#define IDM_HISTORY_LINK6 156 -+#define IDM_HISTORY_LINK7 157 -+#define IDM_HISTORY_LINK8 158 -+#define IDM_HISTORY_LINK9 159 -+#define IDT_UPDATE_STATS 160 -+#define IDM_ACTUAL_SIZE 172 -+#define IDM_ZOOM_IN 173 -+#define IDM_ZOOM_OUT 174 -+#define IDD_AUTH 176 -+#define IDD_PROXY 178 -+#define IDD_SERVER_TRUST 179 -+#define IDR_ACCELERATORS_PRE 180 -+#define IDB_TOOLBAR 181 -+#define IDC_EMPTY_URL_CACHE 1000 -+#define IDC_RETURN_FREE_MEMORY 1001 -+#define IDC_EMPTY_WEBCORE_CACHE 1002 -+#define IDC_CHECK1 1003 -+#define IDC_HEAP_OBJECTS 1005 -+#define IDC_GC_JSC 1006 -+#define IDC_RESERVED_VM 1007 -+#define IDC_COMMITTED_VM 1008 -+#define IDC_FREE_LIST_BYTES 1009 -+#define IDC_IMAGES_OBJECT_COUNT 1011 -+#define IDC_CSS_OBJECT_COUNT 1012 -+#define IDC_XSL_OBJECT_COUNT 1013 -+#define IDC_JSC_OBJECT_COUNT 1014 -+#define IDC_TOTAL_OBJECT_COUNT 1015 -+#define IDC_IMAGES_BYTES 1016 -+#define IDC_CSS_BYTES 1017 -+#define IDC_XSL_BYTES 1018 -+#define IDC_JSC_BYTES 1019 -+#define IDC_TOTAL_BYTES 1020 -+#define IDC_IMAGES_LIVE_COUNT 1021 -+#define IDC_CSS_LIVE_COUNT 1022 -+#define IDC_XSL_LIVE_COUNT 1023 -+#define IDC_JSC_LIVE_COUNT 1024 -+#define IDC_TOTAL_LIVE_COUNT 1025 -+#define IDC_IMAGES_DECODED_COUNT 1026 -+#define IDC_CSS_DECODED_COUNT 1027 -+#define IDC_XSL_DECODED_COUNT 1028 -+#define IDC_JSC_DECODED_COUNT 1029 -+#define IDC_TOTAL_DECODED 1030 -+#define IDC_IMAGES_PURGEABLE_COUNT 1031 -+#define IDC_CSS_PURGEABLE_COUNT 1032 -+#define IDC_XSL_PURGEABLE_COUNT 1033 -+#define IDC_JSC_PURGEABLE_COUNT 1034 -+#define IDC_TOTAL_PURGEABLE 1035 -+#define IDC_TOTAL_JSC_HEAP_OBJECTS 1036 -+#define IDC_GLOBAL_JSC_HEAP_OBJECTS 1037 -+#define IDC_PROTECTED_JSC_HEAP_OBJECTS 1038 -+#define IDC_STATIC56 1039 -+#define IDC_STATIC57 1040 -+#define IDC_JSC_HEAP_SIZE 1041 -+#define IDC_JSC_HEAP_FREE 1042 -+#define IDC_BUTTON5 1043 -+#define IDC_TOTAL_FONT_OBJECTS 1044 -+#define IDC_Message 1044 -+#define IDC_INACTIVE_FONT_OBJECTS 1045 -+#define IDC_GLYPH_PAGES 1046 -+#define IDC_PAGE_URL_MAPPINGS 1047 -+#define IDC_RETAINED_PAGE_URLS 1048 -+#define IDC_SITE_ICON_RECORDS 1049 -+#define IDC_TOTAL_FONT_OBJECTS5 1050 -+#define IDC_SITE_ICONS_WITH_DATA 1051 -+#define IDC_USER_AGENT_INPUT 1052 -+#define IDC_AUTH_USER 1053 -+#define IDC_AUTH_PASSWORD 1054 -+#define IDC_URL_BAR 1055 -+#define IDC_REALM_TEXT 1056 -+#define IDC_PROXY_URL 1057 -+#define IDC_PROXY_DEFAULT 1058 -+#define IDC_PROXY_CUSTOM 1059 -+#define IDC_PROXY_EXCLUDE 1060 -+#define IDC_PROXY_DISABLE 1061 -+#define IDC_SERVER_TRUST_TEXT 1062 -+#define IDM_NEW_WEBKIT_WINDOW 32776 -+#define IDM_NEW_WEBKITLEGACY_WINDOW 32777 -+#define IDM_RELOAD 32779 -+#define IDM_CLOSE_WINDOW 32780 -+#define IDM_GO_HOME 32781 -+#define IDC_STATIC -1 -+ -+// Next default values for new objects -+// -+#ifdef APSTUDIO_INVOKED -+#ifndef APSTUDIO_READONLY_SYMBOLS -+#define _APS_NO_MFC 1 -+#define _APS_NEXT_RESOURCE_VALUE 182 -+#define _APS_NEXT_COMMAND_VALUE 32783 -+#define _APS_NEXT_CONTROL_VALUE 1063 -+#define _APS_NEXT_SYMED_VALUE 110 -+#endif -+#endif -diff --git a/Tools/Playwright/win/PlaywrightReplace.h b/Tools/Playwright/win/PlaywrightReplace.h -new file mode 100644 -index 0000000000000000000000000000000000000000..dd134b879ea6aee23826e9ed2f6773d8c1466118 ---- /dev/null -+++ b/Tools/Playwright/win/PlaywrightReplace.h -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2013 Alex Christensen. 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. -+ */ -+ -+#pragma once -+ -+// This file is to make it easier for users to manage changes to the internals of Playwright -+ -+static void processCrashReport(const wchar_t* fileName) { ::MessageBox(0, fileName, L"Crash Report", MB_OK); } -diff --git a/Tools/Playwright/win/PlaywrightResource.h b/Tools/Playwright/win/PlaywrightResource.h -new file mode 100644 -index 0000000000000000000000000000000000000000..c60d7b73f18d0e7f220e68c2a22e5d9911bf8960 ---- /dev/null -+++ b/Tools/Playwright/win/PlaywrightResource.h -@@ -0,0 +1,20 @@ -+//{{NO_DEPENDENCIES}} -+// Microsoft Visual C++ generated include file. -+// Used by PlaywrightLauncher.rc -+// -+#define IDD_PLAYWRIGHT_DIALOG 102 -+#define IDI_PLAYWRIGHT 107 -+#define IDR_MAINFRAME 128 -+#define IDC_STATIC -1 -+ -+// Next default values for new objects -+// -+#ifdef APSTUDIO_INVOKED -+#ifndef APSTUDIO_READONLY_SYMBOLS -+#define _APS_NO_MFC 1 -+#define _APS_NEXT_RESOURCE_VALUE 129 -+#define _APS_NEXT_COMMAND_VALUE 32771 -+#define _APS_NEXT_CONTROL_VALUE 1000 -+#define _APS_NEXT_SYMED_VALUE 110 -+#endif -+#endif -diff --git a/Tools/Playwright/win/WebKitBrowserWindow.cpp b/Tools/Playwright/win/WebKitBrowserWindow.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..742a817f8bb8934751d057eca55d11e050255487 ---- /dev/null -+++ b/Tools/Playwright/win/WebKitBrowserWindow.cpp -@@ -0,0 +1,386 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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 "stdafx.h" -+#include "Common.h" -+#include "MainWindow.h" -+#include "PlaywrightLibResource.h" -+#include "WebKitBrowserWindow.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+std::wstring createPEMString(WKCertificateInfoRef certificateInfo) -+{ -+ auto chainSize = WKCertificateInfoGetCertificateChainSize(certificateInfo); -+ -+ std::wstring pems; -+ -+ for (auto i = 0; i < chainSize; i++) { -+ auto certificate = adoptWK(WKCertificateInfoCopyCertificateAtIndex(certificateInfo, i)); -+ auto size = WKDataGetSize(certificate.get()); -+ auto data = WKDataGetBytes(certificate.get()); -+ -+ for (size_t i = 0; i < size; i++) -+ pems.push_back(data[i]); -+ } -+ -+ return replaceString(pems, L"\n", L"\r\n"); -+} -+ -+WebKitBrowserWindow::WebKitBrowserWindow(BrowserWindowClient& client, HWND mainWnd, WKPageConfigurationRef conf) -+ : m_client(client) -+ , m_hMainWnd(mainWnd) -+{ -+ RECT rect = { }; -+ m_view = adoptWK(WKViewCreate(rect, conf, mainWnd)); -+ WKViewSetIsInWindow(m_view.get(), true); -+ -+ auto page = WKViewGetPage(m_view.get()); -+ -+ WKPageNavigationClientV0 navigationClient = { }; -+ navigationClient.base.version = 0; -+ navigationClient.base.clientInfo = this; -+ navigationClient.didReceiveAuthenticationChallenge = didReceiveAuthenticationChallenge; -+ WKPageSetPageNavigationClient(page, &navigationClient.base); -+ -+ WKPageUIClientV14 uiClient = { }; -+ uiClient.base.version = 14; -+ uiClient.base.clientInfo = this; -+ uiClient.createNewPage = createNewPage; -+ uiClient.didNotHandleKeyEvent = didNotHandleKeyEvent; -+ uiClient.close = closeWindow; -+ uiClient.runJavaScriptAlert = runJavaScriptAlert; -+ uiClient.runJavaScriptConfirm = runJavaScriptConfirm; -+ uiClient.runJavaScriptPrompt = runJavaScriptPrompt; -+ uiClient.runBeforeUnloadConfirmPanel = runBeforeUnloadConfirmPanel; -+ uiClient.handleJavaScriptDialog = handleJavaScriptDialog; -+ WKPageSetPageUIClient(page, &uiClient.base); -+ -+ WKPageStateClientV0 stateClient = { }; -+ stateClient.base.version = 0; -+ stateClient.base.clientInfo = this; -+ stateClient.didChangeTitle = didChangeTitle; -+ stateClient.didChangeIsLoading = didChangeIsLoading; -+ stateClient.didChangeEstimatedProgress = didChangeEstimatedProgress; -+ stateClient.didChangeActiveURL = didChangeActiveURL; -+ WKPageSetPageStateClient(page, &stateClient.base); -+ -+ WKPagePolicyClientV1 policyClient = { }; -+ policyClient.base.version = 1; -+ policyClient.base.clientInfo = this; -+ policyClient.decidePolicyForResponse_deprecatedForUseWithV0 = decidePolicyForResponse; -+ WKPageSetPagePolicyClient(page, &policyClient.base); -+ resetZoom(); -+} -+ -+WebKitBrowserWindow::~WebKitBrowserWindow() -+{ -+ if (m_alertDialog) { -+ WKRelease(m_alertDialog); -+ m_alertDialog = NULL; -+ } -+ -+ if (m_confirmDialog) { -+ WKRelease(m_confirmDialog); -+ m_confirmDialog = NULL; -+ } -+ -+ if (m_promptDialog) { -+ WKRelease(m_promptDialog); -+ m_promptDialog = NULL; -+ } -+ -+ if (m_beforeUnloadDialog) { -+ WKRelease(m_beforeUnloadDialog); -+ m_beforeUnloadDialog = NULL; -+ } -+} -+ -+HWND WebKitBrowserWindow::hwnd() -+{ -+ return WKViewGetWindow(m_view.get()); -+} -+ -+HRESULT WebKitBrowserWindow::loadURL(const BSTR& url) -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ WKPageLoadURL(page, createWKURL(_bstr_t(url)).get()); -+ return true; -+} -+ -+void WebKitBrowserWindow::reload() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ WKPageReload(page); -+} -+ -+void WebKitBrowserWindow::navigateForwardOrBackward(bool forward) -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ if (forward) -+ WKPageGoForward(page); -+ else -+ WKPageGoBack(page); -+} -+ -+void WebKitBrowserWindow::launchInspector() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ auto inspector = WKPageGetInspector(page); -+ WKInspectorShow(inspector); -+} -+ -+void WebKitBrowserWindow::setUserAgent(_bstr_t& customUAString) -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ auto ua = createWKString(customUAString); -+ WKPageSetCustomUserAgent(page, ua.get()); -+} -+ -+_bstr_t WebKitBrowserWindow::userAgent() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ auto ua = adoptWK(WKPageCopyUserAgent(page)); -+ return createString(ua.get()).c_str(); -+} -+ -+void WebKitBrowserWindow::resetZoom() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ WKPageSetPageZoomFactor(page, WebCore::deviceScaleFactorForWindow(hwnd())); -+} -+ -+void WebKitBrowserWindow::zoomIn() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ double s = WKPageGetPageZoomFactor(page); -+ WKPageSetPageZoomFactor(page, s * 1.25); -+} -+ -+void WebKitBrowserWindow::zoomOut() -+{ -+ auto page = WKViewGetPage(m_view.get()); -+ double s = WKPageGetPageZoomFactor(page); -+ WKPageSetPageZoomFactor(page, s * 0.8); -+} -+ -+static WebKitBrowserWindow& toWebKitBrowserWindow(const void *clientInfo) -+{ -+ return *const_cast(static_cast(clientInfo)); -+} -+ -+void WebKitBrowserWindow::didChangeTitle(const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ auto page = WKViewGetPage(thisWindow.m_view.get()); -+ WKRetainPtr title = adoptWK(WKPageCopyTitle(page)); -+ std::wstring titleString = createString(title.get()) + L" [WebKit]"; -+ SetWindowText(thisWindow.m_hMainWnd, titleString.c_str()); -+} -+ -+void WebKitBrowserWindow::didChangeIsLoading(const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ thisWindow.m_client.progressFinished(); -+} -+ -+void WebKitBrowserWindow::didChangeEstimatedProgress(const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ auto page = WKViewGetPage(thisWindow.m_view.get()); -+ thisWindow.m_client.progressChanged(WKPageGetEstimatedProgress(page)); -+} -+ -+void WebKitBrowserWindow::didChangeActiveURL(const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ auto page = WKViewGetPage(thisWindow.m_view.get()); -+ WKRetainPtr url = adoptWK(WKPageCopyActiveURL(page)); -+ thisWindow.m_client.activeURLChanged(createString(url.get())); -+} -+ -+void WebKitBrowserWindow::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef challenge, const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ auto protectionSpace = WKAuthenticationChallengeGetProtectionSpace(challenge); -+ auto decisionListener = WKAuthenticationChallengeGetDecisionListener(challenge); -+ auto authenticationScheme = WKProtectionSpaceGetAuthenticationScheme(protectionSpace); -+ -+ if (authenticationScheme == kWKProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) { -+ if (thisWindow.canTrustServerCertificate(protectionSpace)) { -+ WKRetainPtr username = createWKString("accept server trust"); -+ WKRetainPtr password = createWKString(""); -+ WKRetainPtr wkCredential = adoptWK(WKCredentialCreate(username.get(), password.get(), kWKCredentialPersistenceForSession)); -+ WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get()); -+ return; -+ } -+ } else { -+ WKRetainPtr realm(WKProtectionSpaceCopyRealm(protectionSpace)); -+ -+ if (auto credential = askCredential(thisWindow.hwnd(), createString(realm.get()))) { -+ WKRetainPtr username = createWKString(credential->username); -+ WKRetainPtr password = createWKString(credential->password); -+ WKRetainPtr wkCredential = adoptWK(WKCredentialCreate(username.get(), password.get(), kWKCredentialPersistenceForSession)); -+ WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get()); -+ return; -+ } -+ } -+ -+ WKAuthenticationDecisionListenerUseCredential(decisionListener, nullptr); -+} -+ -+bool WebKitBrowserWindow::canTrustServerCertificate(WKProtectionSpaceRef protectionSpace) -+{ -+ auto host = createString(adoptWK(WKProtectionSpaceCopyHost(protectionSpace)).get()); -+ auto certificateInfo = adoptWK(WKProtectionSpaceCopyCertificateInfo(protectionSpace)); -+ auto verificationError = WKCertificateInfoGetVerificationError(certificateInfo.get()); -+ auto description = createString(adoptWK(WKCertificateInfoCopyVerificationErrorDescription(certificateInfo.get())).get()); -+ auto pem = createPEMString(certificateInfo.get()); -+ -+ auto it = m_acceptedServerTrustCerts.find(host); -+ if (it != m_acceptedServerTrustCerts.end() && it->second == pem) -+ return true; -+ -+ std::wstring textString = L"[HOST] " + host + L"\r\n"; -+ textString.append(L"[ERROR] " + std::to_wstring(verificationError) + L"\r\n"); -+ textString.append(L"[DESCRIPTION] " + description + L"\r\n"); -+ textString.append(pem); -+ -+ if (askServerTrustEvaluation(hwnd(), textString)) { -+ m_acceptedServerTrustCerts.emplace(host, pem); -+ return true; -+ } -+ -+ return false; -+} -+ -+void WebKitBrowserWindow::closeWindow(WKPageRef page, const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ PostMessage(thisWindow.m_hMainWnd, WM_CLOSE, 0, 0); -+} -+ -+void WebKitBrowserWindow::runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ WKRetain(listener); -+ thisWindow.m_alertDialog = listener; -+} -+ -+void WebKitBrowserWindow::runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ WKRetain(listener); -+ thisWindow.m_confirmDialog = listener; -+} -+ -+void WebKitBrowserWindow::runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ WKRetain(listener); -+ thisWindow.m_promptDialog = listener; -+} -+ -+void WebKitBrowserWindow::runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ WKRetain(listener); -+ thisWindow.m_beforeUnloadDialog = listener; -+} -+ -+void WebKitBrowserWindow::handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ if (thisWindow.m_alertDialog) { -+ WKPageRunJavaScriptAlertResultListenerCall(thisWindow.m_alertDialog); -+ WKRelease(thisWindow.m_alertDialog); -+ thisWindow.m_alertDialog = NULL; -+ } -+ -+ if (thisWindow.m_confirmDialog) { -+ WKPageRunJavaScriptConfirmResultListenerCall(thisWindow.m_confirmDialog, accept); -+ WKRelease(thisWindow.m_confirmDialog); -+ thisWindow.m_confirmDialog = NULL; -+ } -+ -+ if (thisWindow.m_promptDialog) { -+ WKPageRunJavaScriptPromptResultListenerCall(thisWindow.m_promptDialog, accept ? value : NULL); -+ WKRelease(thisWindow.m_promptDialog); -+ thisWindow.m_promptDialog = NULL; -+ } -+ -+ if (thisWindow.m_beforeUnloadDialog) { -+ WKPageRunBeforeUnloadConfirmPanelResultListenerCall(thisWindow.m_beforeUnloadDialog, accept); -+ WKRelease(thisWindow.m_beforeUnloadDialog); -+ thisWindow.m_beforeUnloadDialog = NULL; -+ } -+} -+ -+WKPageRef WebKitBrowserWindow::createPageCallback(WKPageConfigurationRef configuration) -+{ -+ return WebKitBrowserWindow::createViewCallback(configuration, true); -+} -+ -+WKPageRef WebKitBrowserWindow::createViewCallback(WKPageConfigurationRef configuration, bool navigate) -+{ -+ auto* newWindow = new MainWindow(); -+ bool ok = newWindow->init(hInst, configuration); -+ if (navigate) -+ newWindow->browserWindow()->loadURL(_bstr_t("about:blank").GetBSTR()); -+ -+ auto* newBrowserWindow = newWindow->browserWindow(); -+ return WKViewGetPage(newBrowserWindow->m_view.get()); -+} -+ -+ -+WKPageRef WebKitBrowserWindow::createNewPage(WKPageRef, WKPageConfigurationRef configuration, WKNavigationActionRef, WKWindowFeaturesRef, const void*) -+{ -+ // Retain popups as per API contract. -+ WKRetainPtr newPage = createViewCallback(configuration, false); -+ return newPage.leakRef(); -+} -+ -+void WebKitBrowserWindow::didNotHandleKeyEvent(WKPageRef, WKNativeEventPtr event, const void* clientInfo) -+{ -+ auto& thisWindow = toWebKitBrowserWindow(clientInfo); -+ PostMessage(thisWindow.m_hMainWnd, event->message, event->wParam, event->lParam); -+} -+ -+void WebKitBrowserWindow::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -+{ -+ if (WKURLResponseIsAttachment(response)) -+ WKFramePolicyListenerDownload(listener); -+ else -+ WKFramePolicyListenerUse(listener); -+} -diff --git a/Tools/Playwright/win/WebKitBrowserWindow.h b/Tools/Playwright/win/WebKitBrowserWindow.h -new file mode 100644 -index 0000000000000000000000000000000000000000..29e11623eac55a979db444df1d5a04106caf5431 ---- /dev/null -+++ b/Tools/Playwright/win/WebKitBrowserWindow.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2018 Sony Interactive Entertainment Inc. -+ * -+ * 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. ``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 -+ * 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. -+ */ -+#pragma once -+ -+#include "Common.h" -+#include -+#include -+#include -+ -+class BrowserWindowClient { -+public: -+ virtual void progressChanged(double) = 0; -+ virtual void progressFinished() = 0; -+ virtual void activeURLChanged(std::wstring) = 0; -+}; -+ -+class WebKitBrowserWindow { -+public: -+ static WKPageRef createPageCallback(WKPageConfigurationRef); -+ WebKitBrowserWindow(BrowserWindowClient&, HWND mainWnd, WKPageConfigurationRef); -+ ~WebKitBrowserWindow(); -+ -+ HRESULT loadURL(const BSTR& url); -+ void reload(); -+ void navigateForwardOrBackward(bool forward); -+ void launchInspector(); -+ -+ _bstr_t userAgent(); -+ void setUserAgent(_bstr_t&); -+ -+ void resetZoom(); -+ void zoomIn(); -+ void zoomOut(); -+ -+ bool canTrustServerCertificate(WKProtectionSpaceRef); -+ HWND hwnd(); -+ -+private: -+ static WKPageRef createViewCallback(WKPageConfigurationRef, bool navigate); -+ -+ static void didChangeTitle(const void*); -+ static void didChangeIsLoading(const void*); -+ static void didChangeEstimatedProgress(const void*); -+ static void didChangeActiveURL(const void*); -+ static void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef, const void*); -+ static WKPageRef createNewPage(WKPageRef, WKPageConfigurationRef, WKNavigationActionRef, WKWindowFeaturesRef, const void *); -+ static void closeWindow(WKPageRef, const void*); -+ static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo); -+ static void runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo); -+ static void runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo); -+ static void runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo); -+ static void handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo); -+ static void didNotHandleKeyEvent(WKPageRef, WKNativeEventPtr, const void*); -+ static void decidePolicyForResponse(WKPageRef, WKFrameRef, WKURLResponseRef, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef, const void*); -+ -+ BrowserWindowClient& m_client; -+ WKRetainPtr m_view; -+ HWND m_hMainWnd { nullptr }; -+ ProxySettings m_proxy { }; -+ std::unordered_map m_acceptedServerTrustCerts; -+ WKPageRunJavaScriptAlertResultListenerRef m_alertDialog = { }; -+ WKPageRunJavaScriptConfirmResultListenerRef m_confirmDialog = { }; -+ WKPageRunJavaScriptPromptResultListenerRef m_promptDialog = { }; -+ WKPageRunBeforeUnloadConfirmPanelResultListenerRef m_beforeUnloadDialog = { }; -+}; -diff --git a/Tools/Playwright/win/WinMain.cpp b/Tools/Playwright/win/WinMain.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..b19855c53902fd161f3e42858d5828adae1af464 ---- /dev/null -+++ b/Tools/Playwright/win/WinMain.cpp -@@ -0,0 +1,157 @@ -+/* -+ * Copyright (C) 2006, 2008, 2013-2015 Apple Inc. All rights reserved. -+ * Copyright (C) 2009, 2011 Brent Fulgham. All rights reserved. -+ * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved. -+ * Copyright (C) 2013 Alex Christensen. 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. ``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 -+ * 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. -+ */ -+ -+#pragma warning(disable: 4091) -+ -+#include "stdafx.h" -+#include "Common.h" -+#include "MainWindow.h" -+#include "PlaywrightLibResource.h" -+#include "PlaywrightReplace.h" -+#include -+#include -+#include -+#include -+#include "WebKitBrowserWindow.h" -+#include -+#include -+ -+SOFT_LINK_LIBRARY(user32); -+SOFT_LINK_OPTIONAL(user32, SetProcessDpiAwarenessContext, BOOL, STDAPICALLTYPE, (DPI_AWARENESS_CONTEXT)); -+ -+WKRetainPtr toWK(const std::string& string) -+{ -+ return adoptWK(WKStringCreateWithUTF8CString(string.c_str())); -+} -+ -+std::string toUTF8String(const wchar_t* src, size_t srcLength) -+{ -+ int length = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, 0, 0, nullptr, nullptr); -+ std::vector buffer(length); -+ size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr); -+ return { buffer.data(), actualLength }; -+} -+ -+int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpstrCmdLine, _In_ int nCmdShow) -+{ -+#ifdef _CRTDBG_MAP_ALLOC -+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); -+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); -+#endif -+ -+ MSG msg { }; -+ HACCEL hAccelTable, hPreAccelTable; -+ -+ INITCOMMONCONTROLSEX InitCtrlEx; -+ -+ InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); -+ InitCtrlEx.dwICC = 0x00004000; // ICC_STANDARD_CLASSES; -+ InitCommonControlsEx(&InitCtrlEx); -+ -+ auto options = parseCommandLine(); -+ if (options.inspectorPipe) { -+ WKInspectorInitializeRemoteInspectorPipe( -+ WebKitBrowserWindow::createPageCallback, -+ []() { PostQuitMessage(0); }); -+ } -+ -+ if (options.useFullDesktop) -+ computeFullDesktopFrame(); -+ -+ // Init COM -+ OleInitialize(nullptr); -+ -+ if (SetProcessDpiAwarenessContextPtr()) -+ SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE); -+ -+ MainWindow::configure(options.headless, options.noStartupWindow); -+ -+ if (!options.noStartupWindow) { -+ auto configuration = adoptWK(WKWebsiteDataStoreConfigurationCreate()); -+ if (options.userDataDir.length()) { -+ std::string profileFolder = toUTF8String(options.userDataDir, options.userDataDir.length()); -+ WKWebsiteDataStoreConfigurationSetApplicationCacheDirectory(configuration.get(), toWK(profileFolder + "\\ApplicationCache").get()); -+ WKWebsiteDataStoreConfigurationSetNetworkCacheDirectory(configuration.get(), toWK(profileFolder + "\\Cache").get()); -+ WKWebsiteDataStoreConfigurationSetCacheStorageDirectory(configuration.get(), toWK(profileFolder + "\\CacheStorage").get()); -+ WKWebsiteDataStoreConfigurationSetIndexedDBDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\IndexedDB").get()); -+ WKWebsiteDataStoreConfigurationSetLocalStorageDirectory(configuration.get(), toWK(profileFolder + "\\LocalStorage").get()); -+ WKWebsiteDataStoreConfigurationSetWebSQLDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\WebSQL").get()); -+ WKWebsiteDataStoreConfigurationSetMediaKeysStorageDirectory(configuration.get(), toWK(profileFolder + "\\MediaKeys").get()); -+ WKWebsiteDataStoreConfigurationSetResourceLoadStatisticsDirectory(configuration.get(), toWK(profileFolder + "\\ResourceLoadStatistics").get()); -+ WKWebsiteDataStoreConfigurationSetServiceWorkerRegistrationDirectory(configuration.get(), toWK(profileFolder + "\\ServiceWorkers").get()); -+ } -+ auto context = adoptWK(WKContextCreateWithConfiguration(nullptr)); -+ auto dataStore = adoptWK(WKWebsiteDataStoreCreateWithConfiguration(configuration.get())); -+ WKContextSetPrimaryDataStore(context.get(), dataStore.get()); -+ -+ auto* mainWindow = new MainWindow(); -+ HRESULT hr = mainWindow->init(hInst, context.get(), dataStore.get()); -+ if (FAILED(hr)) -+ goto exit; -+ -+ if (options.requestedURL.length()) -+ mainWindow->loadURL(options.requestedURL.GetBSTR()); -+ else -+ mainWindow->goHome(); -+ } -+ -+ hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_PLAYWRIGHT)); -+ hPreAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATORS_PRE)); -+ -+#pragma warning(disable:4509) -+ -+ // Main message loop: -+ __try { -+ while (GetMessage(&msg, nullptr, 0, 0)) { -+ if (TranslateAccelerator(msg.hwnd, hPreAccelTable, &msg)) -+ continue; -+ bool processed = false; -+ if (MainWindow::isInstance(msg.hwnd)) -+ processed = TranslateAccelerator(msg.hwnd, hAccelTable, &msg); -+ if (!processed) { -+ TranslateMessage(&msg); -+ DispatchMessage(&msg); -+ } -+ } -+ } __except(createCrashReport(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) { } -+ -+exit: -+#ifdef _CRTDBG_MAP_ALLOC -+ _CrtDumpMemoryLeaks(); -+#endif -+ -+ // Shut down COM. -+ OleUninitialize(); -+ -+ return static_cast(msg.wParam); -+} -+ -+extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpstrCmdLine, int nCmdShow) -+{ -+ return wWinMain(hInstance, hPrevInstance, lpstrCmdLine, nCmdShow); -+} -diff --git a/Tools/Playwright/win/resource.h b/Tools/Playwright/win/resource.h -new file mode 100644 -index 0000000000000000000000000000000000000000..6a2168457084e26663486a741d39f84beb38e0b5 ---- /dev/null -+++ b/Tools/Playwright/win/resource.h -@@ -0,0 +1,27 @@ -+//{{NO_DEPENDENCIES}} -+// Microsoft Visual C++ generated include file. -+// Used by WinLauncher.rc -+// -+#define IDC_MYICON 2 -+#define IDD_WINLAUNCHER_DIALOG 102 -+#define IDS_APP_TITLE 103 -+#define IDD_ABOUTBOX 103 -+#define IDM_ABOUT 104 -+#define IDM_EXIT 105 -+#define IDI_WINLAUNCHER 107 -+#define IDI_SMALL 108 -+#define IDC_WINLAUNCHER 109 -+#define IDR_MAINFRAME 128 -+#define IDC_STATIC -1 -+ -+// Next default values for new objects -+// -+#ifdef APSTUDIO_INVOKED -+#ifndef APSTUDIO_READONLY_SYMBOLS -+#define _APS_NO_MFC 1 -+#define _APS_NEXT_RESOURCE_VALUE 129 -+#define _APS_NEXT_COMMAND_VALUE 32771 -+#define _APS_NEXT_CONTROL_VALUE 1000 -+#define _APS_NEXT_SYMED_VALUE 110 -+#endif -+#endif -diff --git a/Tools/Playwright/win/small.ico b/Tools/Playwright/win/small.ico -new file mode 100644 -index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 -Binary files /dev/null and b/Tools/Playwright/win/small.ico differ -diff --git a/Tools/Playwright/win/stdafx.cpp b/Tools/Playwright/win/stdafx.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..3c4e5e52a16a300e36f4f9d8c5c490634ed02257 ---- /dev/null -+++ b/Tools/Playwright/win/stdafx.cpp -@@ -0,0 +1,33 @@ -+/* -+ * Copyright (C) 2006 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. ``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 -+ * 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. -+ */ -+ -+// stdafx.cpp : source file that includes just the standard includes -+// Spinneret.pch will be the pre-compiled header -+// stdafx.obj will contain the pre-compiled type information -+ -+#include "stdafx.h" -+ -+// TODO: reference any additional headers you need in STDAFX.H -+// and not in this file -diff --git a/Tools/Playwright/win/stdafx.h b/Tools/Playwright/win/stdafx.h -new file mode 100644 -index 0000000000000000000000000000000000000000..8436fba636da15aa7a9f2f9e6b6667908d7c7b85 ---- /dev/null -+++ b/Tools/Playwright/win/stdafx.h -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2006 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. ``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 -+ * 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. -+ */ -+ -+// stdafx.h : include file for standard system include files, -+// or project specific include files that are used frequently, but -+// are changed infrequently -+// -+ -+#pragma once -+ -+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE) -+#include "cmakeconfig.h" -+#endif -+ -+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -+ -+// Needed for limit defines, like INTMAX_MAX, which is used by the std C++ library -+#ifndef __STDC_LIMIT_MACROS -+#define __STDC_LIMIT_MACROS -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#if 0 -+// Visual Studio Leak Detection -+// -+#if defined(_MSC_VER) && defined(_DEBUG) -+#define _CRTDBG_MAP_ALLOC -+#include -+#include -+#endif -+#endif -diff --git a/Tools/Playwright/win/toolbar.bmp b/Tools/Playwright/win/toolbar.bmp -new file mode 100644 -index 0000000000000000000000000000000000000000..f06d7f785a8743513db6aeb3361f4094237c2c3d -Binary files /dev/null and b/Tools/Playwright/win/toolbar.bmp differ diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit index 099d33a4b9b9cdf432cd1026ea6aae0cb9257a77..0d771ef83c5e53e3d1525b19aa6ccb8687e01c76 100755 --- a/Tools/Scripts/build-webkit diff --git a/browser_patches/webkit/src/Tools/Playwright/Configurations/Base.xcconfig b/browser_patches/webkit/src/Tools/Playwright/Configurations/Base.xcconfig new file mode 100644 index 0000000000..fc61d5227c --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Configurations/Base.xcconfig @@ -0,0 +1,87 @@ +// Copyright (C) 2010-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. ``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 +// 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? "../../../../Internal/Configurations/HaveInternalSDK.xcconfig" +#include "SDKVariant.xcconfig" + +USE_INTERNAL_SDK = $(USE_INTERNAL_SDK_$(CONFIGURATION)); +USE_INTERNAL_SDK_Production = YES; +USE_INTERNAL_SDK_Debug = $(HAVE_INTERNAL_SDK); +USE_INTERNAL_SDK_Release = $(HAVE_INTERNAL_SDK); + +GCC_PREPROCESSOR_DEFINITIONS = DISABLE_LEGACY_WEBKIT_DEPRECATIONS $(inherited); + +CLANG_CXX_LANGUAGE_STANDARD = gnu++1z; +CLANG_CXX_LIBRARY = libc++; +CLANG_ENABLE_OBJC_WEAK = YES; +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; +PREBINDING = NO +GCC_C_LANGUAGE_STANDARD = gnu99 +GCC_ENABLE_CPP_EXCEPTIONS = NO; +GCC_PRECOMPILE_PREFIX_HEADER = YES +ENABLE_STRICT_OBJC_MSGSEND = YES; +GCC_TREAT_WARNINGS_AS_ERRORS = YES +CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; +CLANG_WARN_BOOL_CONVERSION = YES; +CLANG_WARN_COMMA = YES; +CLANG_WARN_CONSTANT_CONVERSION = YES; +CLANG_WARN_EMPTY_BODY = YES; +CLANG_WARN_ENUM_CONVERSION = YES; +CLANG_WARN_INFINITE_RECURSION = YES; +CLANG_WARN_INT_CONVERSION = YES; +CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; +CLANG_WARN_STRICT_PROTOTYPES = YES; +CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; +CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; +CLANG_WARN_SUSPICIOUS_MOVE = YES; +CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; +CLANG_WARN_UNREACHABLE_CODE = YES; +GCC_WARN_64_TO_32_BIT_CONVERSION = YES; +GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; +GCC_WARN_ABOUT_RETURN_TYPE = YES; +GCC_WARN_UNINITIALIZED_AUTOS = YES; +GCC_WARN_UNUSED_FUNCTION = YES +GCC_WARN_UNUSED_VARIABLE = YES +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; +GCC_WARN_UNDECLARED_SELECTOR = YES; +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; +CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; +GCC_VERSION = com.apple.compilers.llvm.clang.1_0; +WARNING_CFLAGS = -Wall -W -Wno-unused-parameter +GCC_NO_COMMON_BLOCKS = YES; + +SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx tvos tvsimulator watchos watchsimulator; + +TARGET_MAC_OS_X_VERSION_MAJOR = $(TARGET_MAC_OS_X_VERSION_MAJOR$(MACOSX_DEPLOYMENT_TARGET:suffix:identifier)); +TARGET_MAC_OS_X_VERSION_MAJOR_13 = 101300; +TARGET_MAC_OS_X_VERSION_MAJOR_14 = 101400; +TARGET_MAC_OS_X_VERSION_MAJOR_15 = 101500; +TARGET_MAC_OS_X_VERSION_MAJOR_16 = 101600; + +SDKROOT = macosx.internal; + +OTHER_CFLAGS = $(ASAN_OTHER_CFLAGS); +OTHER_CPLUSPLUSFLAGS = $(ASAN_OTHER_CPLUSPLUSFLAGS); +OTHER_LDFLAGS = $(ASAN_OTHER_LDFLAGS); + +CODE_SIGN_IDENTITY = -; diff --git a/browser_patches/webkit/src/Tools/Playwright/Configurations/DebugRelease.xcconfig b/browser_patches/webkit/src/Tools/Playwright/Configurations/DebugRelease.xcconfig new file mode 100644 index 0000000000..44dc1139c2 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Configurations/DebugRelease.xcconfig @@ -0,0 +1,45 @@ +// Copyright (C) 2010, 2013 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. ``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 +// 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 "Base.xcconfig" + +ARCHS = $(ARCHS_STANDARD_32_64_BIT); + +ONLY_ACTIVE_ARCH = YES; + +TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); + +MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR)) +MACOSX_DEPLOYMENT_TARGET_101300 = 10.13; +MACOSX_DEPLOYMENT_TARGET_101400 = 10.14; +MACOSX_DEPLOYMENT_TARGET_101500 = 10.15; +MACOSX_DEPLOYMENT_TARGET_101600 = 10.16; + +GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + +SDKROOT = $(SDKROOT_$(USE_INTERNAL_SDK)); +SDKROOT_ = macosx; +SDKROOT_YES = macosx.internal; + +WK_CCACHE_DIR = $(SRCROOT)/../ccache; +#include "../../ccache/ccache.xcconfig" diff --git a/browser_patches/webkit/src/Tools/Playwright/Configurations/Playwright.xcconfig b/browser_patches/webkit/src/Tools/Playwright/Configurations/Playwright.xcconfig new file mode 100644 index 0000000000..d05c841a5b --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Configurations/Playwright.xcconfig @@ -0,0 +1,30 @@ +// Copyright (C) 2010 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. ``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 +// 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. + +PRODUCT_NAME = Playwright +PRODUCT_BUNDLE_IDENTIFIER = org.webkit.$(PRODUCT_NAME:rfc1034identifier) +GCC_PREFIX_HEADER = mac/Playwright_Prefix.pch +INFOPLIST_FILE = mac/Info.plist +EXCLUDED_SOURCE_FILE_NAMES[sdk=iphone*] = * +OTHER_LDFLAGS[sdk=macosx*] = $(inherited) -framework Cocoa -framework WebKit +STRIP_STYLE = debugging; diff --git a/browser_patches/webkit/src/Tools/Playwright/Configurations/SDKVariant.xcconfig b/browser_patches/webkit/src/Tools/Playwright/Configurations/SDKVariant.xcconfig new file mode 100644 index 0000000000..fcdf7e65a6 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Configurations/SDKVariant.xcconfig @@ -0,0 +1,45 @@ +// Copyright (C) 2019 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. ``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 +// 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. + +WK_EMPTY_ = YES; +WK_NOT_ = YES; +WK_NOT_YES = NO; + +WK_ALTERNATE_FRAMEWORKS_DIR = $(WK_ALTERNATE_FRAMEWORKS_DIR_$(SDK_VARIANT)); +WK_ALTERNATE_FRAMEWORKS_DIR_iosmac = /System/iOSSupport; +WK_USE_ALTERNATE_FRAMEWORKS_DIR = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_FRAMEWORKS_DIR))); + +WK_ALTERNATE_PLATFORM_NAME = $(WK_ALTERNATE_PLATFORM_NAME_$(SDK_VARIANT)); +WK_ALTERNATE_PLATFORM_NAME_iosmac = maccatalyst; +WK_USE_ALTERNATE_PLATFORM_NAME = $(WK_NOT_$(WK_EMPTY_$(WK_ALTERNATE_PLATFORM_NAME))); + +WK_ALTERNATE_WEBKIT_SDK_PATH = $(WK_ALTERNATE_WEBKIT_SDK_PATH_$(WK_USE_ALTERNATE_FRAMEWORKS_DIR)); +WK_ALTERNATE_WEBKIT_SDK_PATH_YES = $(WK_ALTERNATE_FRAMEWORKS_DIR)/; + +WK_PLATFORM_NAME = $(WK_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME)); +WK_PLATFORM_NAME_ALTERNATE_YES = $(WK_ALTERNATE_PLATFORM_NAME); +WK_PLATFORM_NAME_ALTERNATE_NO = $(PLATFORM_NAME); + +EFFECTIVE_PLATFORM_NAME = $(EFFECTIVE_PLATFORM_NAME_ALTERNATE_$(WK_USE_ALTERNATE_PLATFORM_NAME)); +EFFECTIVE_PLATFORM_NAME_ALTERNATE_YES = -$(WK_ALTERNATE_PLATFORM_NAME); +EFFECTIVE_PLATFORM_NAME_ALTERNATE_NO = $(EFFECTIVE_PLATFORM_NAME); diff --git a/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.h b/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.h new file mode 100644 index 0000000000..9971d4c102 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2010 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. + */ + +@interface MBToolbarItem : NSToolbarItem +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.m b/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.m new file mode 100644 index 0000000000..56f7778915 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/MBToolbarItem.m @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 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 "MBToolbarItem.h" + +@implementation MBToolbarItem + +- (void)validate +{ + [self setEnabled:[[self target] validateUserInterfaceItem:self]]; +} + +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/Makefile b/browser_patches/webkit/src/Tools/Playwright/Makefile new file mode 100644 index 0000000000..58e5242838 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Makefile @@ -0,0 +1,21 @@ +# Build Playwright only on SnowLeopard and later. + +OSX_VERSION ?= $(shell sw_vers -productVersion | cut -d. -f 2) +BUILD_PLAYWRIGHT = $(shell (( $(OSX_VERSION) >= 6 )) && echo "YES" ) + +ifeq "$(BUILD_PLAYWRIGHT)" "YES" + +SCRIPTS_PATH = ../Scripts +include ../../Makefile.shared + +else + +all: ; + +debug d development dev develop: ; + +release r deployment dep deploy: ; + +clean: ; + +endif diff --git a/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/project.pbxproj b/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..75a945e72d --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/project.pbxproj @@ -0,0 +1,264 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF336A /* AppDelegate.m */; }; + 51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 51E244F911EFCE07008228D2 /* MBToolbarItem.m */; }; + BC329487116A92E2008635D1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329486116A92E2008635D1 /* main.m */; }; + BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC329497116A941B008635D1 /* BrowserWindowController.m */; }; + BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58150DA1D0A300B3202A /* MainMenu.xib */; }; + BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC3294A2116A9852008635D1 /* BrowserWindow.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1AFFEF761860EE6800DA465F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 1AFFEF781860EE6800DA465F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 1DDD58150DA1D0A300B3202A /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = mac/MainMenu.xib; sourceTree = ""; }; + 256AC3D80F4B6AC300CF336A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = mac/AppDelegate.h; sourceTree = ""; }; + 256AC3D90F4B6AC300CF336A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = mac/AppDelegate.m; sourceTree = ""; }; + 256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Playwright_Prefix.pch; path = mac/Playwright_Prefix.pch; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEB /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 37BAF90620218053000EA87A /* Playwright.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Playwright.entitlements; sourceTree = ""; }; + 51E244F811EFCE07008228D2 /* MBToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBToolbarItem.h; sourceTree = ""; }; + 51E244F911EFCE07008228D2 /* MBToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBToolbarItem.m; sourceTree = ""; }; + 8D1107320486CEB800E47091 /* Playwright.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Playwright.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SDKVariant.xcconfig; sourceTree = ""; }; + BC329486116A92E2008635D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = mac/main.m; sourceTree = ""; }; + BC329496116A941B008635D1 /* BrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserWindowController.h; path = mac/BrowserWindowController.h; sourceTree = ""; }; + BC329497116A941B008635D1 /* BrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserWindowController.m; path = mac/BrowserWindowController.m; sourceTree = ""; }; + BC3294A2116A9852008635D1 /* BrowserWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = BrowserWindow.xib; path = mac/BrowserWindow.xib; sourceTree = ""; }; + BC72B89A11E57E8A001EB4EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = mac/Info.plist; sourceTree = ""; }; + BCA8CBDD11E578A000812FB8 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = ""; }; + BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = ""; }; + BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Playwright.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47091 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000002 /* Playwright */ = { + isa = PBXGroup; + children = ( + 256AC3D80F4B6AC300CF336A /* AppDelegate.h */, + 256AC3D90F4B6AC300CF336A /* AppDelegate.m */, + BC72B89A11E57E8A001EB4EB /* Info.plist */, + BC329486116A92E2008635D1 /* main.m */, + 51E244F811EFCE07008228D2 /* MBToolbarItem.h */, + 51E244F911EFCE07008228D2 /* MBToolbarItem.m */, + 37BAF90620218053000EA87A /* Playwright.entitlements */, + BC329496116A941B008635D1 /* BrowserWindowController.h */, + BC329497116A941B008635D1 /* BrowserWindowController.m */, + ); + name = Playwright; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBC /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEB /* AppKit.framework */, + 1AFFEF781860EE6800DA465F /* CoreData.framework */, + 29B97325FDCFA39411CA2CEB /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBC /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47091 /* Playwright.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEB /* Playwright */ = { + isa = PBXGroup; + children = ( + 256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */, + 080E96DDFE201D6D7F000002 /* Playwright */, + 29B97317FDCFA39411CA2CEB /* Resources */, + BCA8CBDA11E5787800812FB8 /* Configurations */, + 29B97323FDCFA39411CA2CEB /* Frameworks */, + 19C28FACFE9D520D11CA2CBC /* Products */, + ); + name = Playwright; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEB /* Resources */ = { + isa = PBXGroup; + children = ( + BC3294A2116A9852008635D1 /* BrowserWindow.xib */, + 1DDD58150DA1D0A300B3202A /* MainMenu.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A2FEA54F0111CA2CBC /* Other Frameworks */, + 1AFFEF761860EE6800DA465F /* Cocoa.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BCA8CBDA11E5787800812FB8 /* Configurations */ = { + isa = PBXGroup; + children = ( + BCA8CBDD11E578A000812FB8 /* Base.xcconfig */, + BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */, + BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */, + A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */, + ); + path = Configurations; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47091 /* Playwright */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */; + buildPhases = ( + 8D1107290486CEB800E47091 /* Resources */, + 8D11072C0486CEB800E47091 /* Sources */, + 8D11072E0486CEB800E47091 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Playwright; + productInstallPath = "$(HOME)/Applications"; + productName = Playwright; + productReference = 8D1107320486CEB800E47091 /* Playwright.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEC /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 1000; + TargetAttributes = { + 8D1107260486CEB800E47091 = { + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + }; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEB /* Playwright */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D1107260486CEB800E47091 /* Playwright */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47091 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BC72B89611E57E0F001EB4EB /* BrowserWindow.xib in Resources */, + BC72B89511E57E07001EB4EB /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47091 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 256AC3DA0F4B6AC300CF336A /* AppDelegate.m in Sources */, + BC329487116A92E2008635D1 /* main.m in Sources */, + 51E244FA11EFCE07008228D2 /* MBToolbarItem.m in Sources */, + BC329498116A941B008635D1 /* BrowserWindowController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */; + buildSettings = { + }; + name = Release; + }; + C01FCF4F08A954540054247C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */; + buildSettings = { + GCC_OPTIMIZATION_LEVEL = 0; + }; + name = Debug; + }; + C01FCF5008A954540054247C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247C /* Build configuration list for PBXNativeTarget "Playwright" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247C /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Playwright" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247C /* Debug */, + C01FCF5008A954540054247C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEC /* Project object */; +} diff --git a/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme b/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme new file mode 100644 index 0000000000..00fb6b0006 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/Playwright.xcodeproj/xcshareddata/xcschemes/Playwright.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.h b/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.h new file mode 100644 index 0000000000..ccc73af47f --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 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 +#import + +@interface WebViewDialog : NSObject +@property (nonatomic, strong) WKWebView *webView; +@property (nonatomic, copy) void (^completionHandler)(BOOL accept, NSString* value); +@end + +@interface BrowserAppDelegate : NSObject { + NSMutableSet *_headlessWindows; + NSMutableSet *_browserContexts; + bool _headless; + bool _noStartupWindow; + NSMutableSet *_dialogs; + NSString* _initialURL; + NSString* _userDataDir; + IBOutlet NSMenuItem *_newWebKit2WindowItem; +} + +@end + +@interface NSApplication (PlaywrightApplicationExtensions) + +- (BrowserAppDelegate *)browserAppDelegate; + +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.m b/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.m new file mode 100644 index 0000000000..d46e0dbe96 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/AppDelegate.m @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2010-2016 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 "AppDelegate.h" + +#import "BrowserWindowController.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +@implementation NSApplication (PlaywrightApplicationExtensions) + +- (BrowserAppDelegate *)browserAppDelegate +{ + return (BrowserAppDelegate *)[self delegate]; +} + +@end + +@interface NSApplication (TouchBar) +@property (getter=isAutomaticCustomizeTouchBarMenuItemEnabled) BOOL automaticCustomizeTouchBarMenuItemEnabled; + +@property (readonly, nonatomic) WKWebViewConfiguration *defaultConfiguration; + +@end + +@implementation WebViewDialog +- (void)dealloc +{ + [_webView release]; + _webView = nil; + [super dealloc]; +} +@end + +enum { + _NSBackingStoreUnbuffered = 3 +}; + +NSString* const ActivityReason = @"Batch headless process"; +const NSActivityOptions ActivityOptions = + (NSActivityUserInitiatedAllowingIdleSystemSleep | + NSActivityLatencyCritical) & + ~(NSActivitySuddenTerminationDisabled | + NSActivityAutomaticTerminationDisabled); + +@implementation BrowserAppDelegate + +- (id)init +{ + self = [super init]; + + if (!self) + return nil; + + _initialURL = nil; + _userDataDir = nil; + NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + NSRange subargs = NSMakeRange(1, [arguments count] - 1); + NSArray *subArray = [arguments subarrayWithRange:subargs]; + + for (NSString *argument in subArray) { + if (![argument hasPrefix:@"--"]) + _initialURL = argument; + if ([argument hasPrefix:@"--user-data-dir="]) { + NSRange range = NSMakeRange(16, [argument length] - 16); + _userDataDir = [[argument substringWithRange:range] copy]; + } + } + + _headless = [arguments containsObject: @"--headless"]; + _noStartupWindow = [arguments containsObject: @"--no-startup-window"]; + _browserContexts = [[NSMutableSet alloc] init]; + + if (_headless) { + _headlessWindows = [[NSMutableSet alloc] init]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; + [[NSProcessInfo processInfo] beginActivityWithOptions:ActivityOptions + reason:ActivityReason]; + _dialogs = [[NSMutableSet alloc] init]; + } else { + [NSApp activateIgnoringOtherApps:YES]; + } + if ([arguments containsObject: @"--inspector-pipe"]) + [_WKBrowserInspector initializeRemoteInspectorPipe:self headless:_headless]; + return self; +} + +- (void)awakeFromNib +{ + if ([NSApp respondsToSelector:@selector(setAutomaticCustomizeTouchBarMenuItemEnabled:)]) + [NSApp setAutomaticCustomizeTouchBarMenuItemEnabled:YES]; +} + +- (WKWebsiteDataStore *)persistentDataStore +{ + static WKWebsiteDataStore *dataStore; + + if (!dataStore) { + _WKWebsiteDataStoreConfiguration *configuration = [[[_WKWebsiteDataStoreConfiguration alloc] init] autorelease]; + if (_userDataDir) { + NSURL *cookieFile = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/cookie.db", _userDataDir]]; + [configuration _setCookieStorageFile:cookieFile]; + + NSURL *applicationCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ApplicationCache", _userDataDir]]; + [configuration setApplicationCacheDirectory:applicationCacheDirectory]; + + NSURL *cacheStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/CacheStorage", _userDataDir]]; + [configuration _setCacheStorageDirectory:cacheStorageDirectory]; + + NSURL *indexedDBDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/IndexedDB", _userDataDir]]; + [configuration _setIndexedDBDatabaseDirectory:indexedDBDirectory]; + + NSURL *localStorageDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/LocalStorage", _userDataDir]]; + [configuration _setWebStorageDirectory:localStorageDirectory]; + + NSURL *mediaCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaCache", _userDataDir]]; + [configuration setMediaCacheDirectory:mediaCacheDirectory]; + + NSURL *mediaKeysDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MediaKeys", _userDataDir]]; + [configuration setMediaKeysStorageDirectory:mediaKeysDirectory]; + + NSURL *networkCacheDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/NetworkCache", _userDataDir]]; + [configuration setNetworkCacheDirectory:networkCacheDirectory]; + + NSURL *loadStatsDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ResourceLoadStatistics", _userDataDir]]; + [configuration _setResourceLoadStatisticsDirectory:loadStatsDirectory]; + + NSURL *serviceWorkersDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/ServiceWorkers", _userDataDir]]; + [configuration _setServiceWorkerRegistrationDirectory:serviceWorkersDirectory]; + + NSURL *webSqlDirectory = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/WebSQL", _userDataDir]]; + [configuration _setWebSQLDatabaseDirectory:webSqlDirectory]; + } + dataStore = [[WKWebsiteDataStore alloc] _initWithConfiguration:configuration]; + } + + return dataStore; +} + +- (WKWebViewConfiguration *)defaultConfiguration +{ + static WKWebViewConfiguration *configuration; + + if (!configuration) { + configuration = [[WKWebViewConfiguration alloc] init]; + configuration.websiteDataStore = [self persistentDataStore]; + configuration.preferences._fullScreenEnabled = YES; + configuration.preferences._developerExtrasEnabled = YES; + configuration.preferences._mediaDevicesEnabled = YES; + configuration.preferences._mockCaptureDevicesEnabled = YES; + configuration.preferences._hiddenPageDOMTimerThrottlingEnabled = NO; + configuration.preferences._hiddenPageDOMTimerThrottlingAutoIncreases = NO; + configuration.preferences._pageVisibilityBasedProcessSuppressionEnabled = NO; + configuration.preferences._domTimersThrottlingEnabled = NO; + configuration.preferences._requestAnimationFrameEnabled = YES; + _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; + processConfiguration.forceOverlayScrollbars = YES; + configuration.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration AndDataStore:configuration.websiteDataStore] autorelease]; + } + return configuration; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + if (!_headless) + [self _updateNewWindowKeyEquivalents]; + + if (_noStartupWindow) + return; + + [self createNewPage:0]; + _initialURL = nil; +} + +- (void)_updateNewWindowKeyEquivalents +{ + NSString *normalWindowEquivalent = @"n"; + _newWebKit2WindowItem.keyEquivalentModifierMask = NSEventModifierFlagCommand; + _newWebKit2WindowItem.keyEquivalent = normalWindowEquivalent; +} + +#pragma mark WKBrowserInspectorDelegate + +- (WKWebViewConfiguration *) sessionConfiguration:(uint64_t)sessionID +{ + for (_WKBrowserContext *browserContext in _browserContexts) { + if ([[browserContext dataStore] sessionID] != sessionID) + continue; + WKWebViewConfiguration *configuration = [[[self defaultConfiguration] copy] autorelease]; + configuration.websiteDataStore = [browserContext dataStore]; + configuration.processPool = [browserContext processPool]; + return configuration; + } + return [self defaultConfiguration]; +} + +- (WKWebView *)createNewPage:(uint64_t)sessionID +{ + NSString* urlString = _initialURL ? _initialURL : @"about:blank"; + WKWebViewConfiguration *configuration = [self sessionConfiguration:sessionID]; + if (_headless) + return [self createHeadlessPage:configuration withURL:urlString]; + return [self createHeadfulPage:configuration withURL:urlString]; +} + +- (WKWebView *)createHeadfulPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString +{ + // WebView lifecycle will control the BrowserWindowController life times. + BrowserWindowController *controller = [[BrowserWindowController alloc] initWithConfiguration:configuration]; + if (!controller) + return nil; + [controller loadURLString:urlString]; + return [controller webView]; +} + +- (WKWebView *)createHeadlessPage:(WKWebViewConfiguration *)configuration withURL:(NSString*)urlString +{ + NSRect rect = NSMakeRect(0, 0, 1280, 720); + NSScreen *firstScreen = [[NSScreen screens] objectAtIndex:0]; + NSRect windowRect = NSOffsetRect(rect, -10000, [firstScreen frame].size.height - rect.size.height + 10000); + NSWindow* window = [[NSWindow alloc] initWithContentRect:windowRect styleMask:NSWindowStyleMaskBorderless backing:(NSBackingStoreType)_NSBackingStoreUnbuffered defer:YES]; + + WKWebView* webView = [[WKWebView alloc] initWithFrame:[window.contentView bounds] configuration:configuration]; + webView._windowOcclusionDetectionEnabled = NO; + if (!webView) + return nil; + + webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + [window.contentView addSubview:webView]; + if (urlString) { + NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlString]; + [webView loadRequest:[NSURLRequest requestWithURL:url]]; + } + [_headlessWindows addObject:window]; + webView.navigationDelegate = self; + webView.UIDelegate = self; + return [webView autorelease]; +} + +- (_WKBrowserContext *)createBrowserContext +{ + _WKBrowserContext *browserContext = [[_WKBrowserContext alloc] init]; + _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; + processConfiguration.forceOverlayScrollbars = YES; + browserContext.dataStore = [WKWebsiteDataStore nonPersistentDataStore]; + browserContext.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease]; + [browserContext.processPool _setDownloadDelegate:self]; + [_browserContexts addObject:browserContext]; + return browserContext; +} + +- (void)deleteBrowserContext:(uint64_t)sessionID +{ + for (_WKBrowserContext *browserContext in _browserContexts) { + if ([[browserContext dataStore] sessionID] != sessionID) + continue; + [_browserContexts removeObject:browserContext]; + return; + } +} + +- (void)quit +{ + [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; +} + +#pragma mark WKUIDelegate + +- (void)webViewDidClose:(WKWebView *)webView { + for (NSWindow *window in _headlessWindows) { + if (webView.window != window) + continue; + [webView removeFromSuperview]; + [window close]; + [_headlessWindows removeObject:window]; + break; + } +} + +- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler +{ + WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; + dialog.webView = webView; + dialog.completionHandler = ^void (BOOL accept, NSString* value) { + completionHandler(); + }; + [_dialogs addObject:dialog]; +} + +- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler +{ + WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; + dialog.webView = webView; + dialog.completionHandler = ^void (BOOL accept, NSString* value) { + completionHandler(accept); + }; + [_dialogs addObject:dialog]; +} + +- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler +{ + WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; + dialog.webView = webView; + dialog.completionHandler = ^void (BOOL accept, NSString* value) { + completionHandler(accept && value ? value : nil); + }; + [_dialogs addObject:dialog]; +} + +- (void)_webView:(WKWebView *)webView runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler +{ + WebViewDialog* dialog = [[WebViewDialog alloc] autorelease]; + dialog.webView = webView; + dialog.completionHandler = ^void (BOOL accept, NSString* value) { + completionHandler(accept); + }; + [_dialogs addObject:dialog]; +} + +- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value +{ + for (WebViewDialog *dialog in _dialogs) { + if (dialog.webView != webView) + continue; + dialog.completionHandler(accept, value); + [_dialogs removeObject:dialog]; + break; + } +} + +- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures +{ + return [self createHeadlessPage:configuration withURL:nil]; +} + +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler +{ + LOG(@"decidePolicyForNavigationAction"); + + if (navigationAction._canHandleRequest) { + decisionHandler(WKNavigationActionPolicyAllow); + return; + } + decisionHandler(WKNavigationActionPolicyCancel); +} + +- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler +{ + if (![navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { + decisionHandler(WKNavigationResponsePolicyAllow); + return; + } + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)navigationResponse.response; + + NSString *disposition = [[httpResponse allHeaderFields] objectForKey:@"Content-Disposition"]; + if (disposition && [disposition hasPrefix:@"attachment"]) { + decisionHandler(_WKNavigationResponsePolicyBecomeDownload); + return; + } + decisionHandler(WKNavigationResponsePolicyAllow); +} + +#pragma mark _WKDownloadDelegate + +- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler +{ + completionHandler(NO, @""); +} + +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindow.xib b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindow.xib new file mode 100644 index 0000000000..f6f3d8e3a0 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindow.xib @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.h b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.h new file mode 100644 index 0000000000..4dbf13c8fb --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010 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. + */ + +@class WKWebView; + +@interface BrowserWindowController : NSWindowController + +- (IBAction)goBack:(id)sender; +- (IBAction)goForward:(id)sender; +- (IBAction)reload:(id)sender; +- (IBAction)saveAsPDF:(id)sender; +- (IBAction)saveAsWebArchive:(id)sender; +- (IBAction)zoomIn:(id)sender; +- (IBAction)zoomOut:(id)sender; +- (IBAction)resetZoom:(id)sender; +- (IBAction)showHideWebInspector:(id)sender; + +- (IBAction)setPageScale:(id)sender; +- (IBAction)setViewScale:(id)sender; +- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration; +- (void)loadURLString:(NSString *)urlString; +- (WKWebView *)webView; + +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.m b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.m new file mode 100644 index 0000000000..c48697f7cf --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/BrowserWindowController.m @@ -0,0 +1,839 @@ +/* + * Copyright (C) 2010-2016 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 "BrowserWindowController.h" + +#import "AppDelegate.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +static void* keyValueObservingContext = &keyValueObservingContext; + +@interface PlaywrightNSTextFinder : NSTextFinder + +@property (nonatomic, copy) dispatch_block_t hideInterfaceCallback; + +@end + +@implementation PlaywrightNSTextFinder + +- (void)performAction:(NSTextFinderAction)op +{ + [super performAction:op]; + + if (op == NSTextFinderActionHideFindInterface && _hideInterfaceCallback) + _hideInterfaceCallback(); +} + +@end + +@interface BrowserWindowController () +@end + +@implementation BrowserWindowController { + IBOutlet NSProgressIndicator *progressIndicator; + IBOutlet NSButton *reloadButton; + IBOutlet NSButton *backButton; + IBOutlet NSButton *forwardButton; + IBOutlet NSButton *share; + IBOutlet NSToolbar *toolbar; + IBOutlet NSTextField *urlText; + IBOutlet NSView *containerView; + IBOutlet NSButton *toggleUseShrinkToFitButton; + + WKWebViewConfiguration *_configuration; + WKWebView *_webView; + BOOL _zoomTextOnly; + BOOL _isPrivateBrowsingWindow; + NSAlert* _alert; + + BOOL _useShrinkToFit; + + PlaywrightNSTextFinder *_textFinder; + NSView *_textFindBarView; + BOOL _findBarVisible; +} + +- (id)initWithWindow:(NSWindow *)window +{ + self = [super initWithWindow:window]; + return self; +} + +- (void)windowDidLoad +{ + [share sendActionOn:NSEventMaskLeftMouseDown]; + [super windowDidLoad]; +} + +- (IBAction)openLocation:(id)sender +{ + [[self window] makeFirstResponder:urlText]; +} + +- (NSString *)addProtocolIfNecessary:(NSString *)address +{ + if ([address rangeOfString:@"://"].length > 0) + return address; + + if ([address hasPrefix:@"data:"]) + return address; + + if ([address hasPrefix:@"about:"]) + return address; + + return [@"http://" stringByAppendingString:address]; +} + +- (IBAction)share:(id)sender +{ + NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:@[ self.currentURL ]]; + picker.delegate = self; + [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSRectEdgeMinY]; +} + +- (IBAction)showHideWebView:(id)sender +{ + self.mainContentView.hidden = !self.mainContentView.isHidden; +} + +- (CGFloat)pageScaleForMenuItemTag:(NSInteger)tag +{ + if (tag == 1) + return 1; + if (tag == 2) + return 1.25; + if (tag == 3) + return 1.5; + if (tag == 4) + return 2.0; + + return 1; +} + +- (void)awakeFromNib +{ + _webView = [[WKWebView alloc] initWithFrame:[containerView bounds] configuration:_configuration]; + _webView._windowOcclusionDetectionEnabled = NO; + + _webView.allowsMagnification = YES; + _webView.allowsBackForwardNavigationGestures = YES; + + [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [containerView addSubview:_webView]; + + [progressIndicator bind:NSHiddenBinding toObject:_webView withKeyPath:@"loading" options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }]; + [progressIndicator bind:NSValueBinding toObject:_webView withKeyPath:@"estimatedProgress" options:nil]; + + [_webView addObserver:self forKeyPath:@"title" options:0 context:keyValueObservingContext]; + [_webView addObserver:self forKeyPath:@"URL" options:0 context:keyValueObservingContext]; + + _webView.navigationDelegate = self; + _webView.UIDelegate = self; + + _webView._observedRenderingProgressEvents = _WKRenderingProgressEventFirstLayout + | _WKRenderingProgressEventFirstVisuallyNonEmptyLayout + | _WKRenderingProgressEventFirstPaintWithSignificantArea + | _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering + | _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering; + + _webView.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Safari/605.1.15"; + + _webView._usePlatformFindUI = NO; + + _textFinder = [[PlaywrightNSTextFinder alloc] init]; + _textFinder.incrementalSearchingEnabled = YES; + _textFinder.incrementalSearchingShouldDimContentView = NO; + _textFinder.client = _webView; + _textFinder.findBarContainer = self; + _textFinder.hideInterfaceCallback = ^{ + [_webView _hideFindUI]; + }; + + _zoomTextOnly = NO; +} + +- (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration +{ + if (!(self = [super initWithWindowNibName:@"BrowserWindow"])) + return nil; + _configuration = [configuration copy]; + _isPrivateBrowsingWindow = !_configuration.websiteDataStore.isPersistent; + self.window.styleMask &= ~NSWindowStyleMaskFullSizeContentView; + [self.window makeKeyAndOrderFront:nil]; + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [progressIndicator unbind:NSHiddenBinding]; + [progressIndicator unbind:NSValueBinding]; + + [_textFinder release]; + [_webView release]; + [_configuration release]; + + [super dealloc]; +} + +- (IBAction)fetch:(id)sender +{ + [urlText setStringValue:[self addProtocolIfNecessary:urlText.stringValue]]; + NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlText.stringValue]; + [_webView loadRequest:[NSURLRequest requestWithURL:url]]; +} + +- (IBAction)setPageScale:(id)sender +{ + CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]]; + [_webView _setPageScale:scale withOrigin:CGPointZero]; +} + +- (CGFloat)viewScaleForMenuItemTag:(NSInteger)tag +{ + if (tag == 1) + return 1; + if (tag == 2) + return 0.75; + if (tag == 3) + return 0.5; + if (tag == 4) + return 0.25; + + return 1; +} + +- (IBAction)setViewScale:(id)sender +{ + CGFloat scale = [self viewScaleForMenuItemTag:[sender tag]]; + CGFloat oldScale = [_webView _viewScale]; + + if (scale == oldScale) + return; + + [_webView _setLayoutMode:_WKLayoutModeDynamicSizeComputedFromViewScale]; + + NSRect oldFrame = self.window.frame; + NSSize newFrameSize = NSMakeSize(oldFrame.size.width * (scale / oldScale), oldFrame.size.height * (scale / oldScale)); + [self.window setFrame:NSMakeRect(oldFrame.origin.x, oldFrame.origin.y - (newFrameSize.height - oldFrame.size.height), newFrameSize.width, newFrameSize.height) display:NO animate:NO]; + + [_webView _setViewScale:scale]; +} + +static BOOL areEssentiallyEqual(double a, double b) +{ + double tolerance = 0.001; + return (fabs(a - b) <= tolerance); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-implementations" +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +#pragma GCC diagnostic pop +{ + SEL action = menuItem.action; + + if (action == @selector(saveAsPDF:)) + return YES; + if (action == @selector(saveAsWebArchive:)) + return YES; + + if (action == @selector(zoomIn:)) + return [self canZoomIn]; + if (action == @selector(zoomOut:)) + return [self canZoomOut]; + if (action == @selector(resetZoom:)) + return [self canResetZoom]; + + if (action == @selector(toggleZoomMode:)) + [menuItem setState:_zoomTextOnly ? NSControlStateValueOn : NSControlStateValueOff]; + else if (action == @selector(showHideWebInspector:)) + [menuItem setTitle:_webView._inspector.isVisible ? @"Close Web Inspector" : @"Show Web Inspector"]; + + if (action == @selector(setPageScale:)) + [menuItem setState:areEssentiallyEqual([_webView _pageScale], [self pageScaleForMenuItemTag:[menuItem tag]])]; + + if (action == @selector(setViewScale:)) + [menuItem setState:areEssentiallyEqual([_webView _viewScale], [self viewScaleForMenuItemTag:[menuItem tag]])]; + + return YES; +} + +- (IBAction)reload:(id)sender +{ + [_webView reload]; +} + +- (IBAction)goBack:(id)sender +{ + [_webView goBack]; +} + +- (IBAction)goForward:(id)sender +{ + [_webView goForward]; +} + +- (IBAction)toggleZoomMode:(id)sender +{ + if (_zoomTextOnly) { + _zoomTextOnly = NO; + double currentTextZoom = _webView._textZoomFactor; + _webView._textZoomFactor = 1; + _webView.pageZoom = currentTextZoom; + } else { + _zoomTextOnly = YES; + double currentPageZoom = _webView._pageZoomFactor; + _webView._textZoomFactor = currentPageZoom; + _webView.pageZoom = 1; + } +} + +- (IBAction)resetZoom:(id)sender +{ + if (![self canResetZoom]) + return; + + if (_zoomTextOnly) + _webView._textZoomFactor = 1; + else + _webView.pageZoom = 1; +} + +- (BOOL)canResetZoom +{ + return _zoomTextOnly ? (_webView._textZoomFactor != 1) : (_webView.pageZoom != 1); +} + +- (IBAction)showHideWebInspector:(id)sender +{ + _WKInspector *inspector = _webView._inspector; + if (inspector.isVisible) + [inspector hide]; + else + [inspector show]; +} + +- (NSURL *)currentURL +{ + return _webView.URL; +} + +- (NSView *)mainContentView +{ + return _webView; +} + +- (BOOL)validateUserInterfaceItem:(id )item +{ + SEL action = item.action; + + if (action == @selector(goBack:) || action == @selector(goForward:)) + return [_webView validateUserInterfaceItem:item]; + + return YES; +} + +- (void)validateToolbar +{ + [toolbar validateVisibleItems]; +} + +- (BOOL)windowShouldClose:(id)sender +{ + return YES; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [_webView removeObserver:self forKeyPath:@"title"]; + [_webView removeObserver:self forKeyPath:@"URL"]; + [_webView removeFromSuperview]; + _textFinder.hideInterfaceCallback = nil; + [self release]; +} + +- (void)webViewDidClose:(WKWebView *)webView { + [self.window close]; +} + +#define DefaultMinimumZoomFactor (.5) +#define DefaultMaximumZoomFactor (3.0) +#define DefaultZoomFactorRatio (1.2) + +- (CGFloat)currentZoomFactor +{ + return _zoomTextOnly ? _webView._textZoomFactor : _webView.pageZoom; +} + +- (void)setCurrentZoomFactor:(CGFloat)factor +{ + if (_zoomTextOnly) + _webView._textZoomFactor = factor; + else + _webView.pageZoom = factor; +} + +- (BOOL)canZoomIn +{ + return self.currentZoomFactor * DefaultZoomFactorRatio < DefaultMaximumZoomFactor; +} + +- (void)zoomIn:(id)sender +{ + if (!self.canZoomIn) + return; + + self.currentZoomFactor *= DefaultZoomFactorRatio; +} + +- (BOOL)canZoomOut +{ + return self.currentZoomFactor / DefaultZoomFactorRatio > DefaultMinimumZoomFactor; +} + +- (void)zoomOut:(id)sender +{ + if (!self.canZoomIn) + return; + + self.currentZoomFactor /= DefaultZoomFactorRatio; +} + +- (void)updateTitle:(NSString *)title +{ + if (!title) { + NSURL *url = _webView.URL; + title = url.lastPathComponent ?: url._web_userVisibleString; + } + + self.window.title = [NSString stringWithFormat:@"%@%@ [%d]%@", _isPrivateBrowsingWindow ? @"🙈 " : @"", title, _webView._webProcessIdentifier, @""]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (context != keyValueObservingContext || object != _webView) + return; + + if ([keyPath isEqualToString:@"title"]) + [self updateTitle:_webView.title]; + else if ([keyPath isEqualToString:@"URL"]) + [self updateTextFieldFromURL:_webView.URL]; +} + +- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures +{ + // WebView lifecycle will control the BrowserWindowController life times. + BrowserWindowController *controller = [[BrowserWindowController alloc] initWithConfiguration:configuration]; + return controller->_webView; +} + +- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler +{ + NSAlert* alert = [[NSAlert alloc] init]; + + [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [frame.request.URL absoluteString]]]; + [alert setInformativeText:message]; + [alert addButtonWithTitle:@"OK"]; + + _alert = alert; + [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { + completionHandler(); + [alert release]; + _alert = nil; + }]; +} + +- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler +{ + NSAlert* alert = [[NSAlert alloc] init]; + + [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [frame.request.URL absoluteString]]]; + [alert setInformativeText:message]; + + [alert addButtonWithTitle:@"OK"]; + [alert addButtonWithTitle:@"Cancel"]; + + _alert = alert; + [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { + completionHandler(response == NSAlertFirstButtonReturn); + [alert release]; + _alert = nil; + }]; +} + +- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler +{ + NSAlert* alert = [[NSAlert alloc] init]; + + [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [frame.request.URL absoluteString]]]; + [alert setInformativeText:prompt]; + + [alert addButtonWithTitle:@"OK"]; + [alert addButtonWithTitle:@"Cancel"]; + + NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)]; + [input setStringValue:defaultText]; + [alert setAccessoryView:input]; + + _alert = alert; + [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { + [input validateEditing]; + completionHandler(response == NSAlertFirstButtonReturn ? [input stringValue] : nil); + [alert release]; + _alert = nil; + }]; +} + +- (void)webView:(WKWebView *)webView handleJavaScriptDialog:(BOOL)accept value:(NSString *)value +{ + if (!_alert) + return; + NSTextField* input = (NSTextField*)_alert.accessoryView; + if (accept && input && value) + [input setStringValue:value]; + [self.window endSheet:_alert.window returnCode: accept ? NSAlertFirstButtonReturn : NSModalResponseCancel]; +} + +#if __has_feature(objc_generics) +- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray * URLs))completionHandler +#else +- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler +#endif +{ + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + + openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection; + + [openPanel beginSheetModalForWindow:webView.window completionHandler:^(NSInteger result) { + if (result == NSModalResponseOK) + completionHandler(openPanel.URLs); + else + completionHandler(nil); + }]; +} + +- (void)_webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler +{ + NSAlert *alert = [[NSAlert alloc] init]; + + alert.messageText = [NSString stringWithFormat:@"JavaScript before unload dialog from %@.", [frame.request.URL absoluteString]]; + alert.informativeText = message; + + [alert addButtonWithTitle:@"Leave Page"]; + [alert addButtonWithTitle:@"Stay On Page"]; + + _alert = alert; + [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) { + completionHandler(response == NSAlertFirstButtonReturn); + [alert release]; + _alert = nil; + }]; +} + +- (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo +{ + return WKDragDestinationActionAny; +} + +- (void)updateTextFieldFromURL:(NSURL *)URL +{ + if (!URL) + return; + + if (!URL.absoluteString.length) + return; + + urlText.stringValue = [URL _web_userVisibleString]; +} + +- (void)loadURLString:(NSString *)urlString +{ + // FIXME: We shouldn't have to set the url text here. + [urlText setStringValue:urlString]; + [self fetch:nil]; +} + +- (void)loadHTMLString:(NSString *)HTMLString +{ + [_webView loadHTMLString:HTMLString baseURL:nil]; +} + +static NSSet *dataTypes() +{ + return [WKWebsiteDataStore allWebsiteDataTypes]; +} + +- (IBAction)fetchWebsiteData:(id)sender +{ + [_configuration.websiteDataStore _fetchDataRecordsOfTypes:dataTypes() withOptions:_WKWebsiteDataStoreFetchOptionComputeSizes completionHandler:^(NSArray *websiteDataRecords) { + NSLog(@"did fetch website data %@.", websiteDataRecords); + }]; +} + +- (IBAction)fetchAndClearWebsiteData:(id)sender +{ + [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) { + [_configuration.websiteDataStore removeDataOfTypes:dataTypes() forDataRecords:websiteDataRecords completionHandler:^{ + [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) { + NSLog(@"did clear website data, after clearing data is %@.", websiteDataRecords); + }]; + }]; + }]; +} + +- (IBAction)clearWebsiteData:(id)sender +{ + [_configuration.websiteDataStore removeDataOfTypes:dataTypes() modifiedSince:[NSDate distantPast] completionHandler:^{ + NSLog(@"Did clear website data."); + }]; +} + +- (IBAction)printWebView:(id)sender +{ + [[_webView printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil]; +} + +#pragma mark WKNavigationDelegate + +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler +{ + LOG(@"decidePolicyForNavigationAction"); + + if (navigationAction._canHandleRequest) { + decisionHandler(WKNavigationActionPolicyAllow); + return; + } + decisionHandler(WKNavigationActionPolicyCancel); +} + +- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler +{ + if (![navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { + decisionHandler(WKNavigationResponsePolicyAllow); + return; + } + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)navigationResponse.response; + + NSString *disposition = [[httpResponse allHeaderFields] objectForKey:@"Content-Disposition"]; + if (disposition && [disposition hasPrefix:@"attachment"]) { + decisionHandler(_WKNavigationResponsePolicyBecomeDownload); + return; + } + decisionHandler(WKNavigationResponsePolicyAllow); +} + +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation +{ + LOG(@"didStartProvisionalNavigation: %@", navigation); +} + +- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation +{ + LOG(@"didReceiveServerRedirectForProvisionalNavigation: %@", navigation); +} + +- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error +{ + LOG(@"didFailProvisionalNavigation: %@navigation, error: %@", navigation, error); +} + +- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation +{ + LOG(@"didCommitNavigation: %@", navigation); + [self updateTitle:nil]; +} + +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation +{ + LOG(@"didFinishNavigation: %@", navigation); +} + +- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler +{ + LOG(@"didReceiveAuthenticationChallenge: %@", challenge); + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) { + NSAlert *alert = [[NSAlert alloc] init]; + NSView *container = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 200, 48)] autorelease]; + NSTextField *userInput = [[[NSTextField alloc] initWithFrame:NSMakeRect(0, 24, 200, 24)] autorelease]; + NSTextField *passwordInput = [[[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)] autorelease]; + + [alert setMessageText:[NSString stringWithFormat:@"Log in to %@:%lu.", challenge.protectionSpace.host, challenge.protectionSpace.port]]; + [alert addButtonWithTitle:@"Log in"]; + [alert addButtonWithTitle:@"Cancel"]; + [container addSubview:userInput]; + [container addSubview:passwordInput]; + [alert setAccessoryView:container]; + [userInput setNextKeyView:passwordInput]; + [alert.window setInitialFirstResponder:userInput]; + + [alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse response) { + [userInput validateEditing]; + if (response == NSAlertFirstButtonReturn) + completionHandler(NSURLSessionAuthChallengeUseCredential, [[[NSURLCredential alloc] initWithUser:[userInput stringValue] password:[passwordInput stringValue] persistence:NSURLCredentialPersistenceForSession] autorelease]); + else + completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); + [alert release]; + }]; + return; + } + completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); +} + +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error +{ + LOG(@"didFailNavigation: %@, error %@", navigation, error); +} + +- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView +{ + NSLog(@"WebContent process crashed; reloading"); + [self reload:nil]; +} + +- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents +{ + if (progressEvents & _WKRenderingProgressEventFirstLayout) + LOG(@"renderingProgressDidChange: %@", @"first layout"); + + if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout) + LOG(@"renderingProgressDidChange: %@", @"first visually non-empty layout"); + + if (progressEvents & _WKRenderingProgressEventFirstPaintWithSignificantArea) + LOG(@"renderingProgressDidChange: %@", @"first paint with significant area"); + + if (progressEvents & _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering) + LOG(@"renderingProgressDidChange: %@", @"first layout after suppressed incremental rendering"); + + if (progressEvents & _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering) + LOG(@"renderingProgressDidChange: %@", @"first paint after suppressed incremental rendering"); +} + +- (void)webView:(WKWebView *)webView shouldLoadIconWithParameters:(_WKLinkIconParameters *)parameters completionHandler:(void (^)(void (^)(NSData*)))completionHandler +{ + completionHandler(^void (NSData *data) { + LOG(@"Icon URL %@ received icon data of length %u", parameters.url, (unsigned)data.length); + }); +} + +#pragma mark Find in Page + +- (IBAction)performTextFinderAction:(id)sender +{ + [_textFinder performAction:[sender tag]]; +} + +- (NSView *)findBarView +{ + return _textFindBarView; +} + +- (void)setFindBarView:(NSView *)findBarView +{ + _textFindBarView = findBarView; + _findBarVisible = YES; + [_textFindBarView setFrame:NSMakeRect(0, 0, containerView.bounds.size.width, _textFindBarView.frame.size.height)]; +} + +- (BOOL)isFindBarVisible +{ + return _findBarVisible; +} + +- (void)setFindBarVisible:(BOOL)findBarVisible +{ + _findBarVisible = findBarVisible; + if (findBarVisible) + [containerView addSubview:_textFindBarView]; + else + [_textFindBarView removeFromSuperview]; +} + +- (NSView *)contentView +{ + return _webView; +} + +- (void)findBarViewDidChangeHeight +{ +} + +- (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL authorized))decisionHandler +{ + decisionHandler(true); +} + +- (void)_webView:(WKWebView *)webView includeSensitiveMediaDeviceDetails:(void (^)(BOOL includeSensitiveDetails))decisionHandler +{ + decisionHandler(false); +} + +- (IBAction)saveAsPDF:(id)sender +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + panel.allowedFileTypes = @[ @"pdf" ]; + [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { + if (result == NSModalResponseOK) { + [_webView createPDFWithConfiguration:nil completionHandler:^(NSData *pdfSnapshotData, NSError *error) { + [pdfSnapshotData writeToURL:[panel URL] options:0 error:nil]; + }]; + } + }]; +} + +- (IBAction)saveAsWebArchive:(id)sender +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + panel.allowedFileTypes = @[ @"webarchive" ]; + [panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { + if (result == NSModalResponseOK) { + [_webView createWebArchiveDataWithCompletionHandler:^(NSData *archiveData, NSError *error) { + [archiveData writeToURL:[panel URL] options:0 error:nil]; + }]; + } + }]; +} + +- (WKWebView *)webView +{ + return _webView; +} + +@end diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/CMakeLists.txt b/browser_patches/webkit/src/Tools/Playwright/mac/CMakeLists.txt new file mode 100644 index 0000000000..410d47425b --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/CMakeLists.txt @@ -0,0 +1,43 @@ +set(PLAYWRIGHT_DIR "${TOOLS_DIR}/Playwright/mac") + +#FIXME: This should not need WEBCORE_EXPORT defined. This means we are including WebCore headers, and we should not. +add_definitions("-include Playwright_Prefix.pch -DWEBCORE_EXPORT=") + +set(Playwright_SOURCES + ${PLAYWRIGHT_DIR}/AppDelegate.m + ${PLAYWRIGHT_DIR}/BrowserWindowController.m + ${PLAYWRIGHT_DIR}/main.m + ${TOOLS_DIR}/Playwright/MBToolbarItem.m +) + +set(Playwright_INCLUDE_DIRECTORIES + ${CMAKE_SOURCE_DIR}/Source + ${FORWARDING_HEADERS_DIR} + ${PLAYWRIGHT_DIR} +) + +set(Playwright_LIBRARIES + WebKit +) + +set(CMAKE_EXE_LINKER_FLAGS "-framework Cocoa") + +set(EXECUTABLE_NAME Playwright) +set(PRODUCT_NAME Playwright) + +set(Playwright_Contents_Directory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Playwright.app/Contents) +make_directory(${Playwright_Contents_Directory}/Resources) +add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib + COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib ${PLAYWRIGHT_DIR}/BrowserWindow.xib VERBATIM) +add_custom_command(OUTPUT ${Playwright_Contents_Directory}/Resources/MainMenu.nib + COMMAND ibtool --compile ${Playwright_Contents_Directory}/Resources/MainMenu.nib ${PLAYWRIGHT_DIR}/MainMenu.xib VERBATIM) +add_custom_target(PlaywrightNibs ALL DEPENDS + ${Playwright_Contents_Directory}/Resources/BrowserWindow.nib + ${Playwright_Contents_Directory}/Resources/MainMenu.nib +) + +include_directories(${Playwright_INCLUDE_DIRECTORIES}) +add_executable(Playwright MACOSX_BUNDLE ${Playwright_SOURCES}) +set_target_properties(Playwright PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PLAYWRIGHT_DIR}/Info.plist) +target_link_libraries(Playwright ${Playwright_LIBRARIES}) +add_dependencies(Playwright PlaywrightNibs) diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/Info.plist b/browser_patches/webkit/src/Tools/Playwright/mac/Info.plist new file mode 100644 index 0000000000..4ed50c40f2 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/Info.plist @@ -0,0 +1,56 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + WebKit Browser + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + LSMinimumSystemVersion + ${MACOSX_DEPLOYMENT_TARGET} + CFBundleVersion + 1 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSSupportsAutomaticGraphicsSwitching + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + html + + CFBundleTypeMIMETypes + + text/html + + CFBundleTypeName + HTML + CFBundleTypeRole + Editor + + + + diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/MainMenu.xib b/browser_patches/webkit/src/Tools/Playwright/mac/MainMenu.xib new file mode 100644 index 0000000000..b16d639a1a --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/MainMenu.xib @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/Playwright_Prefix.pch b/browser_patches/webkit/src/Tools/Playwright/mac/Playwright_Prefix.pch new file mode 100644 index 0000000000..ab6e9bce9a --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/Playwright_Prefix.pch @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 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. + */ + +#ifdef __OBJC__ +#import +#import +#endif + +#define ENABLE_LOGGING 0 + +#if ENABLE_LOGGING +#define LOG NSLog +#else +#define LOG(...) ((void)0) +#endif diff --git a/browser_patches/webkit/src/Tools/Playwright/mac/main.m b/browser_patches/webkit/src/Tools/Playwright/mac/main.m new file mode 100644 index 0000000000..ba2ca12482 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/mac/main.m @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 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 + +int main(int argc, char *argv[]) +{ + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitLinkedOnOrAfterEverything"]; + + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/browser_patches/webkit/src/Tools/Playwright/win/CMakeLists.txt b/browser_patches/webkit/src/Tools/Playwright/win/CMakeLists.txt new file mode 100644 index 0000000000..b8076d8a4c --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/CMakeLists.txt @@ -0,0 +1,42 @@ +set(Playwright_INCLUDE_DIRECTORIES + ${PAL_FRAMEWORK_HEADERS_DIR} + ${WebCore_PRIVATE_FRAMEWORK_HEADERS_DIR} + ${WebKit_FRAMEWORK_HEADERS_DIR} + ${WebKit_PRIVATE_FRAMEWORK_HEADERS_DIR} +) + +set(Playwright_SOURCES + Common.cpp + MainWindow.cpp + PlaywrightLib.rc + WebKitBrowserWindow.cpp + WinMain.cpp + stdafx.cpp +) + +set(Playwright_LIBRARIES + DbgHelp + WebKit::WTF + comctl32 + comsupp + comsuppw + shlwapi + WebKit +) + +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MSVC_RUNTIME_LINKER_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wWinMainCRTStartup") + +if (${WTF_PLATFORM_WIN_CAIRO}) + add_definitions(-DWIN_CAIRO) +endif () +add_definitions(-D_UNICODE) +include_directories(${Playwright_INCLUDE_DIRECTORIES}) +add_library(PlaywrightLib SHARED ${Playwright_SOURCES}) +target_link_libraries(PlaywrightLib ${Playwright_LIBRARIES}) + +add_executable(Playwright WIN32 ${TOOLS_DIR}/win/DLLLauncher/DLLLauncherMain.cpp Playwright.rc) +target_link_libraries(Playwright shlwapi) +set_target_properties(Playwright PROPERTIES OUTPUT_NAME "Playwright") + +add_dependencies(Playwright PlaywrightLib) diff --git a/browser_patches/webkit/src/Tools/Playwright/win/Common.cpp b/browser_patches/webkit/src/Tools/Playwright/win/Common.cpp new file mode 100644 index 0000000000..969425bec9 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/Common.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2006, 2008, 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2011 Brent Fulgham. All rights reserved. + * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved. + * Copyright (C) 2013 Alex Christensen. 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. ``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 + * 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 "stdafx.h" +#include "Common.h" + +#include "DialogHelper.h" +#include "PlaywrightLibResource.h" +#include "PlaywrightReplace.h" +#include +#include +#include +#include +#include + +// Global Variables: +HINSTANCE hInst; + +// Support moving the transparent window +POINT s_windowPosition = { 100, 100 }; +SIZE s_windowSize = { 500, 200 }; + +namespace WebCore { +float deviceScaleFactorForWindow(HWND); +} + +void computeFullDesktopFrame() +{ + RECT desktop; + if (!::SystemParametersInfo(SPI_GETWORKAREA, 0, static_cast(&desktop), 0)) + return; + + float scaleFactor = WebCore::deviceScaleFactorForWindow(nullptr); + + s_windowPosition.x = 0; + s_windowPosition.y = 0; + s_windowSize.cx = scaleFactor * (desktop.right - desktop.left); + s_windowSize.cy = scaleFactor * (desktop.bottom - desktop.top); +} + +BOOL WINAPI DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID) +{ + if (reason == DLL_PROCESS_ATTACH) + hInst = dllInstance; + + return TRUE; +} + +bool getAppDataFolder(_bstr_t& directory) +{ + wchar_t appDataDirectory[MAX_PATH]; + if (FAILED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, appDataDirectory))) + return false; + + wchar_t executablePath[MAX_PATH]; + if (!::GetModuleFileNameW(0, executablePath, MAX_PATH)) + return false; + + ::PathRemoveExtensionW(executablePath); + + directory = _bstr_t(appDataDirectory) + L"\\" + ::PathFindFileNameW(executablePath); + + return true; +} + +void createCrashReport(EXCEPTION_POINTERS* exceptionPointers) +{ + _bstr_t directory; + + if (!getAppDataFolder(directory)) + return; + + if (::SHCreateDirectoryEx(0, directory, 0) != ERROR_SUCCESS + && ::GetLastError() != ERROR_FILE_EXISTS + && ::GetLastError() != ERROR_ALREADY_EXISTS) + return; + + std::wstring fileName = std::wstring(static_cast(directory)) + L"\\CrashReport.dmp"; + HANDLE miniDumpFile = ::CreateFile(fileName.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + + if (miniDumpFile && miniDumpFile != INVALID_HANDLE_VALUE) { + + MINIDUMP_EXCEPTION_INFORMATION mdei; + mdei.ThreadId = ::GetCurrentThreadId(); + mdei.ExceptionPointers = exceptionPointers; + mdei.ClientPointers = 0; + +#ifdef _DEBUG + MINIDUMP_TYPE dumpType = MiniDumpWithFullMemory; +#else + MINIDUMP_TYPE dumpType = MiniDumpNormal; +#endif + + ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), miniDumpFile, dumpType, &mdei, 0, 0); + ::CloseHandle(miniDumpFile); + processCrashReport(fileName.c_str()); + } +} + +bool askProxySettings(HWND hwnd, ProxySettings& settings) +{ + class ProxyDialog : public Dialog { + public: + ProxyDialog(ProxySettings& settings) + : settings { settings } + { + } + + protected: + ProxySettings& settings; + + void setup() final + { + auto command = commandForProxyChoice(); + proxyChoice().set(command); + setText(IDC_PROXY_URL, settings.url); + setText(IDC_PROXY_EXCLUDE, settings.excludeHosts); + } + + void ok() final + { + settings.url = getText(IDC_PROXY_URL); + settings.excludeHosts = getText(IDC_PROXY_EXCLUDE); + updateProxyChoice(proxyChoice().get()); + } + + bool validate() final + { + bool valid = true; + + if (proxyChoice().get() == IDC_PROXY_CUSTOM) { + setEnabled(IDC_PROXY_URL, true); + setEnabled(IDC_PROXY_EXCLUDE, true); + + if (!getTextLength(IDC_PROXY_URL)) + valid = false; + } else { + setEnabled(IDC_PROXY_URL, false); + setEnabled(IDC_PROXY_EXCLUDE, false); + } + + return valid; + } + + RadioGroup proxyChoice() + { + return radioGroup(IDC_PROXY_DEFAULT, IDC_PROXY_DISABLE); + } + + int commandForProxyChoice() + { + if (!settings.enable) + return IDC_PROXY_DISABLE; + if (settings.custom) + return IDC_PROXY_CUSTOM; + return IDC_PROXY_DEFAULT; + } + + void updateProxyChoice(int command) + { + switch (command) { + case IDC_PROXY_DEFAULT: + settings.enable = true; + settings.custom = false; + break; + case IDC_PROXY_CUSTOM: + settings.enable = true; + settings.custom = true; + break; + case IDC_PROXY_DISABLE: + settings.enable = false; + settings.custom = false; + break; + default: + break; + } + } + }; + + ProxyDialog dialog { settings }; + return dialog.run(hInst, hwnd, IDD_PROXY); +} + +Optional askCredential(HWND hwnd, const std::wstring& realm) +{ + struct AuthDialog : public Dialog { + std::wstring realm; + Credential credential; + + protected: + void setup() + { + setText(IDC_REALM_TEXT, realm); + } + + void ok() final + { + credential.username = getText(IDC_AUTH_USER); + credential.password = getText(IDC_AUTH_PASSWORD); + } + }; + + AuthDialog dialog; + dialog.realm = realm; + + if (dialog.run(hInst, hwnd, IDD_AUTH)) + return dialog.credential; + return WTF::nullopt; +} + +bool askServerTrustEvaluation(HWND hwnd, const std::wstring& text) +{ + class ServerTrustEvaluationDialog : public Dialog { + public: + ServerTrustEvaluationDialog(const std::wstring& text) + : m_text { text } + { + SendMessage(GetDlgItem(this->hDlg(), IDC_SERVER_TRUST_TEXT), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE); + } + + protected: + std::wstring m_text; + + void setup() + { + setText(IDC_SERVER_TRUST_TEXT, m_text); + } + + void ok() final + { + + } + }; + + ServerTrustEvaluationDialog dialog { text }; + return dialog.run(hInst, hwnd, IDD_SERVER_TRUST); +} + +CommandLineOptions parseCommandLine() +{ + CommandLineOptions options; + + int argc = 0; + WCHAR** argv = CommandLineToArgvW(GetCommandLineW(), &argc); + for (int i = 1; i < argc; ++i) { + if (!wcsicmp(argv[i], L"--desktop")) + options.useFullDesktop = true; + else if (!wcsicmp(argv[i], L"--inspector-pipe")) + options.inspectorPipe = true; + else if (!wcsncmp(argv[i], L"--user-data-dir=", 16)) + options.userDataDir = argv[i] + 16; + else if (!wcsicmp(argv[i], L"--headless")) + options.headless = true; + else if (!wcsicmp(argv[i], L"--no-startup-window")) + options.noStartupWindow = true; + else if (!options.requestedURL) + options.requestedURL = argv[i]; + } + + return options; +} + +std::wstring replaceString(std::wstring src, const std::wstring& oldValue, const std::wstring& newValue) +{ + if (src.empty() || oldValue.empty()) + return src; + + size_t pos = 0; + while ((pos = src.find(oldValue, pos)) != src.npos) { + src.replace(pos, oldValue.length(), newValue); + pos += newValue.length(); + } + + return src; +} + +std::wstring createString(WKStringRef wkString) +{ + size_t maxSize = WKStringGetLength(wkString); + + std::vector wkCharBuffer(maxSize); + size_t actualLength = WKStringGetCharacters(wkString, wkCharBuffer.data(), maxSize); + return std::wstring(wkCharBuffer.data(), actualLength); +} + +std::wstring createString(WKURLRef wkURL) +{ + if (!wkURL) + return { }; + WKRetainPtr url = adoptWK(WKURLCopyString(wkURL)); + return createString(url.get()); +} + +std::string createUTF8String(const wchar_t* src, size_t srcLength) +{ + int length = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, 0, 0, nullptr, nullptr); + std::vector buffer(length); + size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr); + return { buffer.data(), actualLength }; +} + +WKRetainPtr createWKString(_bstr_t str) +{ + auto utf8 = createUTF8String(str, str.length()); + return adoptWK(WKStringCreateWithUTF8CString(utf8.data())); +} + +WKRetainPtr createWKString(const std::wstring& str) +{ + auto utf8 = createUTF8String(str.c_str(), str.length()); + return adoptWK(WKStringCreateWithUTF8CString(utf8.data())); +} + +WKRetainPtr createWKURL(_bstr_t str) +{ + auto utf8 = createUTF8String(str, str.length()); + return adoptWK(WKURLCreateWithUTF8CString(utf8.data())); +} + +WKRetainPtr createWKURL(const std::wstring& str) +{ + auto utf8 = createUTF8String(str.c_str(), str.length()); + return adoptWK(WKURLCreateWithUTF8CString(utf8.data())); +} diff --git a/browser_patches/webkit/src/Tools/Playwright/win/Common.h b/browser_patches/webkit/src/Tools/Playwright/win/Common.h new file mode 100644 index 0000000000..da9b00c96f --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/Common.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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. + */ + +#pragma once + +#include "stdafx.h" +#include +#include +#include +#include + +struct CommandLineOptions { + bool useFullDesktop { }; + bool inspectorPipe { }; + bool headless { }; + bool noStartupWindow { }; + _bstr_t requestedURL; + _bstr_t userDataDir; + + CommandLineOptions() + { + } +}; + +struct Credential { + std::wstring username; + std::wstring password; +}; + +struct ProxySettings { + bool enable { true }; + bool custom { false }; + std::wstring url; + std::wstring excludeHosts; +}; + +void computeFullDesktopFrame(); +bool getAppDataFolder(_bstr_t& directory); +CommandLineOptions parseCommandLine(); +void createCrashReport(EXCEPTION_POINTERS*); +Optional askCredential(HWND, const std::wstring& realm); +bool askProxySettings(HWND, ProxySettings&); + +bool askServerTrustEvaluation(HWND, const std::wstring& text); +std::wstring replaceString(std::wstring src, const std::wstring& oldValue, const std::wstring& newValue); + +extern HINSTANCE hInst; +extern POINT s_windowPosition; +extern SIZE s_windowSize; + +std::wstring createString(WKStringRef wkString); +std::wstring createString(WKURLRef wkURL); +std::string createUTF8String(const wchar_t* src, size_t srcLength); +WKRetainPtr createWKString(_bstr_t str); +WKRetainPtr createWKString(const std::wstring& str); +WKRetainPtr createWKURL(_bstr_t str); +WKRetainPtr createWKURL(const std::wstring& str); diff --git a/browser_patches/webkit/src/Tools/Playwright/win/DialogHelper.h b/browser_patches/webkit/src/Tools/Playwright/win/DialogHelper.h new file mode 100644 index 0000000000..6590fe0025 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/DialogHelper.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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. + */ + +#pragma once + +#include "stdafx.h" +#include +#include + +class Dialog { +public: + bool run(HINSTANCE hInst, HWND hwnd, int dialogId) + { + auto result = DialogBoxParam(hInst, MAKEINTRESOURCE(dialogId), hwnd, doalogProc, reinterpret_cast(this)); + return (result > 0); + } + + static INT_PTR CALLBACK doalogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) + { + if (message == WM_INITDIALOG) + SetWindowLongPtr(hDlg, DWLP_USER, lParam); + else + lParam = GetWindowLongPtr(hDlg, DWLP_USER); + + auto* dialog = reinterpret_cast(lParam); + return dialog->handle(hDlg, message, wParam); + } + +protected: + INT_PTR handle(HWND hDlg, UINT message, WPARAM wParam) + { + switch (message) { + case WM_INITDIALOG: { + m_hDlg = hDlg; + setup(); + update(); + return TRUE; + } + case WM_COMMAND: + int wmId = LOWORD(wParam); + switch (wmId) { + case IDOK: + ok(); + close(true); + return TRUE; + case IDCANCEL: + cancel(); + close(false); + return TRUE; + default: + auto handled = command(wmId); + update(); + return handled; + } + } + return FALSE; + } + + virtual void setup() { } + virtual void update() { updateOkButton(validate()); } + virtual bool validate() { return true; } + virtual void updateOkButton(bool isValid) { setEnabled(IDOK, isValid); } + virtual bool command(int wmId) { return false; } + virtual void ok() { } + virtual void cancel() { } + + void close(bool success) { EndDialog(m_hDlg, success); } + + HWND hDlg() { return m_hDlg; } + + HWND item(int itemId) { return GetDlgItem(m_hDlg, itemId); } + + void setEnabled(int itemId, bool enabled) + { + EnableWindow(item(itemId), enabled); + } + + void setText(int itemId, const std::wstring& str) + { + SetDlgItemText(m_hDlg, itemId, _bstr_t(str.c_str())); + } + + std::wstring getText(int itemId) + { + auto length = getTextLength(itemId); + std::vector buffer(length + 1, 0); + GetWindowText(item(itemId), buffer.data(), length + 1); + return std::wstring { buffer.data() }; + } + + int getTextLength(int itemId) + { + return GetWindowTextLength(item(itemId)); + } + + class RadioGroup { + public: + RadioGroup(Dialog& dialog, int first, int last) + : m_dialog(dialog) + , m_first(first) + , m_last(last) + { + } + + void set(int item) + { + CheckRadioButton(m_dialog.hDlg(), m_first, m_last, item); + } + + int get() + { + for (int id = m_first; id <= m_last; id++) { + if (IsDlgButtonChecked(m_dialog.hDlg(), id) == BST_CHECKED) + return id; + } + return 0; + } + + private: + Dialog& m_dialog; + int m_first; + int m_last; + }; + + RadioGroup radioGroup(int first, int last) + { + return RadioGroup(*this, first, last); + } + + HWND m_hDlg { }; +}; diff --git a/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.cpp b/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.cpp new file mode 100644 index 0000000000..1f2b465478 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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 "stdafx.h" +#include "Common.h" +#include "MainWindow.h" +#include "PlaywrightLibResource.h" +#include "WebKitBrowserWindow.h" +#include + +namespace WebCore { +float deviceScaleFactorForWindow(HWND); +} + +static const wchar_t* kPlaywrightRegistryKey = L"Software\\WebKit\\Playwright"; + +static constexpr int kToolbarImageSize = 24; +static constexpr int kToolbarURLBarIndex = 3; + +static WNDPROC DefEditProc = nullptr; + +static LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM); +static INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); + +std::wstring MainWindow::s_windowClass; +size_t MainWindow::s_numInstances; + +bool MainWindow::s_headless = false; +bool MainWindow::s_noStartupWindow = false; + +void MainWindow::configure(bool headless, bool noStartupWindow) { + s_headless = headless; + s_noStartupWindow = noStartupWindow; +} + +static std::wstring loadString(int id) +{ + constexpr size_t length = 100; + wchar_t buff[length]; + LoadString(hInst, id, buff, length); + return buff; +} + +void MainWindow::registerClass(HINSTANCE hInstance) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + s_windowClass = loadString(IDC_PLAYWRIGHT); + + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PLAYWRIGHT)); + wcex.hCursor = LoadCursor(0, IDC_ARROW); + wcex.hbrBackground = 0; + wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PLAYWRIGHT); + wcex.lpszClassName = s_windowClass.c_str(); + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_PLAYWRIGHT)); + + RegisterClassEx(&wcex); +} + +bool MainWindow::isInstance(HWND hwnd) +{ + wchar_t buff[64]; + if (!GetClassName(hwnd, buff, _countof(buff))) + return false; + return s_windowClass == buff; +} + +MainWindow::MainWindow() +{ + s_numInstances++; +} + +MainWindow::~MainWindow() +{ + s_numInstances--; +} + +void MainWindow::createToolbar(HINSTANCE hInstance) +{ + m_hToolbarWnd = CreateWindowEx(0, TOOLBARCLASSNAME, nullptr, + WS_CHILD | WS_BORDER | TBSTYLE_FLAT | TBSTYLE_LIST | TBSTYLE_TOOLTIPS, 0, 0, 0, 0, + m_hMainWnd, nullptr, hInstance, nullptr); + + if (!m_hToolbarWnd) + return; + + const int ImageListID = 0; + + HIMAGELIST hImageList; + hImageList = ImageList_LoadImage(hInstance, MAKEINTRESOURCE(IDB_TOOLBAR), kToolbarImageSize, 0, CLR_DEFAULT, IMAGE_BITMAP, 0); + + SendMessage(m_hToolbarWnd, TB_SETIMAGELIST, ImageListID, reinterpret_cast(hImageList)); + SendMessage(m_hToolbarWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS); + + const DWORD buttonStyles = BTNS_AUTOSIZE; + + TBBUTTON tbButtons[] = { + { MAKELONG(0, ImageListID), IDM_HISTORY_BACKWARD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Back" }, + { MAKELONG(1, ImageListID), IDM_HISTORY_FORWARD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Forward"}, + { MAKELONG(2, ImageListID), IDM_RELOAD, TBSTATE_ENABLED, buttonStyles, { }, 0, (INT_PTR)L"Reload"}, + { 0, 0, TBSTATE_ENABLED, BTNS_SEP, { }, 0, 0}, // URL bar + }; + + SendMessage(m_hToolbarWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); + SendMessage(m_hToolbarWnd, TB_ADDBUTTONS, _countof(tbButtons), reinterpret_cast(&tbButtons)); + ShowWindow(m_hToolbarWnd, true); + + m_hURLBarWnd = CreateWindow(L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL, 0, 0, 0, 0, m_hToolbarWnd, 0, hInstance, 0); + + DefEditProc = reinterpret_cast(GetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC)); + SetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC, reinterpret_cast(EditProc)); +} + +void MainWindow::resizeToolbar(int parentWidth) +{ + TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; + info.cx = parentWidth - m_toolbarItemsWidth; + SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast(&info)); + SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); + + RECT rect; + SendMessage(m_hToolbarWnd, TB_GETITEMRECT, kToolbarURLBarIndex, reinterpret_cast(&rect)); + MoveWindow(m_hURLBarWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, true); +} + +void MainWindow::rescaleToolbar() +{ + const float scaleFactor = WebCore::deviceScaleFactorForWindow(m_hMainWnd); + const int scaledImageSize = kToolbarImageSize * scaleFactor; + + TBBUTTONINFO info { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_SIZE }; + + info.cx = 0; + SendMessage(m_hToolbarWnd, TB_SETBUTTONINFO, kToolbarURLBarIndex, reinterpret_cast(&info)); + SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0); + + int numItems = SendMessage(m_hToolbarWnd, TB_BUTTONCOUNT, 0, 0); + + RECT rect; + SendMessage(m_hToolbarWnd, TB_GETITEMRECT, numItems-1, reinterpret_cast(&rect)); + m_toolbarItemsWidth = rect.right; +} + +bool MainWindow::init(HINSTANCE hInstance, WKContextRef context, WKWebsiteDataStoreRef dataStore) +{ + auto conf = adoptWK(WKPageConfigurationCreate()); + auto prefs = adoptWK(WKPreferencesCreate()); + + auto pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(createWKString("WinPlaywright").get())); + WKPageConfigurationSetPageGroup(conf.get(), pageGroup.get()); + WKPageGroupSetPreferences(pageGroup.get(), prefs.get()); + + WKPreferencesSetMediaCapabilitiesEnabled(prefs.get(), false); + WKPreferencesSetDeveloperExtrasEnabled(prefs.get(), true); + WKPageConfigurationSetPreferences(conf.get(), prefs.get()); + + WKPageConfigurationSetContext(conf.get(), context); + WKPageConfigurationSetWebsiteDataStore(conf.get(), dataStore); + + return init(hInstance, conf.get()); +} + +bool MainWindow::init(HINSTANCE hInstance, WKPageConfigurationRef conf) +{ + m_configuration = conf; + + registerClass(hInstance); + + auto title = loadString(IDS_APP_TITLE); + + m_hMainWnd = CreateWindowExW(s_headless ? WS_EX_NOACTIVATE : 0, s_windowClass.c_str(), title.c_str(), + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, this); + + if (!m_hMainWnd) + return false; + + if (!s_headless) { + createToolbar(hInstance); + if (!m_hToolbarWnd) + return false; + } + + m_browserWindow.reset(new WebKitBrowserWindow(*this, m_hMainWnd, conf)); + + updateDeviceScaleFactor(); + resizeSubViews(); + + if (s_headless) { + SetMenu(m_hMainWnd, NULL); + } else { + SetFocus(m_hURLBarWnd); + ShowWindow(m_hMainWnd, SW_SHOW); + } + return true; +} + +void MainWindow::resizeSubViews() +{ + RECT rcClient; + GetClientRect(m_hMainWnd, &rcClient); + if (s_headless) { + MoveWindow(m_browserWindow->hwnd(), 0, 0, rcClient.right, rcClient.bottom, true); + return; + } + + resizeToolbar(rcClient.right); + + RECT rect; + GetWindowRect(m_hToolbarWnd, &rect); + POINT toolbarBottom = { 0, rect.bottom }; + ScreenToClient(m_hMainWnd, &toolbarBottom); + auto height = toolbarBottom.y; + MoveWindow(m_browserWindow->hwnd(), 0, height, rcClient.right, rcClient.bottom - height, true); +} + +LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = 0; + MainWindow* thisWindow = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (!thisWindow && message != WM_CREATE) + return DefWindowProc(hWnd, message, wParam, lParam); + + switch (message) { + case WM_ACTIVATE: + switch (LOWORD(wParam)) { + case WA_ACTIVE: + case WA_CLICKACTIVE: + SetFocus(thisWindow->browserWindow()->hwnd()); + } + break; + case WM_CREATE: + SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams)); + break; + case WM_APPCOMMAND: { + auto cmd = GET_APPCOMMAND_LPARAM(lParam); + switch (cmd) { + case APPCOMMAND_BROWSER_BACKWARD: + thisWindow->browserWindow()->navigateForwardOrBackward(false); + result = 1; + break; + case APPCOMMAND_BROWSER_FORWARD: + thisWindow->browserWindow()->navigateForwardOrBackward(true); + result = 1; + break; + case APPCOMMAND_BROWSER_REFRESH: + thisWindow->browserWindow()->reload(); + result = 1; + break; + case APPCOMMAND_BROWSER_STOP: + break; + } + break; + } + case WM_COMMAND: { + int wmId = LOWORD(wParam); + int wmEvent = HIWORD(wParam); + switch (wmEvent) { + case 0: // Menu or BN_CLICKED + case 1: // Accelerator + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + // Parse the menu selections: + switch (wmId) { + case IDC_URL_BAR: + thisWindow->onURLBarEnter(); + break; + case IDM_NEW_WINDOW: { + auto* newWindow = new MainWindow(); + newWindow->init(hInst, thisWindow->m_configuration.get()); + break; + } + case IDM_CLOSE_WINDOW: + PostMessage(hWnd, WM_CLOSE, 0, 0); + break; + case IDM_ABOUT: + DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); + break; + case IDM_WEB_INSPECTOR: + thisWindow->browserWindow()->launchInspector(); + break; + case IDM_HISTORY_BACKWARD: + case IDM_HISTORY_FORWARD: + thisWindow->browserWindow()->navigateForwardOrBackward(wmId == IDM_HISTORY_FORWARD); + break; + case IDM_ACTUAL_SIZE: + thisWindow->browserWindow()->resetZoom(); + break; + case IDM_RELOAD: + thisWindow->browserWindow()->reload(); + break; + case IDM_ZOOM_IN: + thisWindow->browserWindow()->zoomIn(); + break; + case IDM_ZOOM_OUT: + thisWindow->browserWindow()->zoomOut(); + break; + default: + if (!thisWindow->toggleMenuItem(wmId)) + return DefWindowProc(hWnd, message, wParam, lParam); + } + } + break; + case WM_DESTROY: + SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); + delete thisWindow; + if (s_noStartupWindow || s_numInstances > 0) + return 0; + PostQuitMessage(0); + break; + case WM_SIZE: + thisWindow->resizeSubViews(); + break; + case WM_DPICHANGED: { + thisWindow->updateDeviceScaleFactor(); + auto& rect = *reinterpret_cast(lParam); + SetWindowPos(hWnd, nullptr, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE); + break; + } + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return result; +} + +static bool menuItemIsChecked(const MENUITEMINFO& info) +{ + return info.fState & MFS_CHECKED; +} + +bool MainWindow::toggleMenuItem(UINT menuID) +{ + if (s_headless) + return (INT_PTR)FALSE; + + HMENU menu = ::GetMenu(hwnd()); + + MENUITEMINFO info = { }; + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE; + + if (!::GetMenuItemInfo(menu, menuID, FALSE, &info)) + return false; + + BOOL newState = !menuItemIsChecked(info); + info.fState = (newState) ? MFS_CHECKED : MFS_UNCHECKED; + ::SetMenuItemInfo(menu, menuID, FALSE, &info); + + return true; +} + +LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_SETFOCUS: + PostMessage(hWnd, EM_SETSEL, 0, -1); + break; + case WM_CHAR: + if (wParam == 13) { + // Enter Key + ::PostMessage(GetParent(hWnd), static_cast(WM_COMMAND), MAKELPARAM(IDC_URL_BAR, 0), 0); + return 0; + } + break; + } + return CallWindowProc(DefEditProc, hWnd, message, wParam, lParam); +} + +// Message handler for about box. +INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + switch (message) { + case WM_INITDIALOG: + return (INT_PTR)TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { + EndDialog(hDlg, LOWORD(wParam)); + return (INT_PTR)TRUE; + } + break; + } + return (INT_PTR)FALSE; +} + +void MainWindow::loadURL(std::wstring url) +{ + if (::PathFileExists(url.c_str()) || ::PathIsUNC(url.c_str())) { + wchar_t fileURL[INTERNET_MAX_URL_LENGTH]; + DWORD fileURLLength = _countof(fileURL); + + if (SUCCEEDED(::UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0))) + url = fileURL; + } + if (url.find(L"://") == url.npos && url.find(L"about:blank") == url.npos) + url = L"http://" + url; + + if (FAILED(m_browserWindow->loadURL(_bstr_t(url.c_str())))) + return; + + if (!s_headless) + SetFocus(m_browserWindow->hwnd()); +} + +void MainWindow::onURLBarEnter() +{ + if (s_headless) + return; + wchar_t url[INTERNET_MAX_URL_LENGTH]; + GetWindowText(m_hURLBarWnd, url, INTERNET_MAX_URL_LENGTH); + loadURL(url); +} + +void MainWindow::updateDeviceScaleFactor() +{ + if (s_headless) + return; + if (m_hURLBarFont) + ::DeleteObject(m_hURLBarFont); + + rescaleToolbar(); + + RECT rect; + GetClientRect(m_hToolbarWnd, &rect); + int fontHeight = 20; + + m_hURLBarFont = ::CreateFont(fontHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, + OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FF_DONTCARE, L"Tahoma"); + ::SendMessage(m_hURLBarWnd, static_cast(WM_SETFONT), reinterpret_cast(m_hURLBarFont), TRUE); +} + +void MainWindow::activeURLChanged(std::wstring url) +{ + if (s_headless) + return; + SetWindowText(m_hURLBarWnd, url.c_str()); +} diff --git a/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.h b/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.h new file mode 100644 index 0000000000..4c9bb23645 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/MainWindow.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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. + */ + +#pragma once + +#include "WebKitBrowserWindow.h" + +#include +#include +#include +#include +#include + +class MainWindow : public BrowserWindowClient { +public: + static void configure(bool headless, bool noStartupWindow); + + MainWindow(); + + ~MainWindow(); + bool init(HINSTANCE hInstance, WKContextRef, WKWebsiteDataStoreRef); + bool init(HINSTANCE hInstance, WKPageConfigurationRef); + + void resizeSubViews(); + HWND hwnd() const { return m_hMainWnd; } + WebKitBrowserWindow* browserWindow() const { return m_browserWindow.get(); } + + void loadURL(std::wstring); + + static bool isInstance(HWND); + +private: + static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); + static void registerClass(HINSTANCE hInstance); + static std::wstring s_windowClass; + static size_t s_numInstances; + static bool s_headless; + static bool s_noStartupWindow; + + bool toggleMenuItem(UINT menuID); + void onURLBarEnter(); + void updateDeviceScaleFactor(); + + void createToolbar(HINSTANCE); + void resizeToolbar(int); + void rescaleToolbar(); + + // BrowserWindowClient + void activeURLChanged(std::wstring) final; + + HWND m_hMainWnd { nullptr }; + HWND m_hToolbarWnd { nullptr }; + HWND m_hURLBarWnd { nullptr }; + HWND m_hProgressIndicator { nullptr }; + HWND m_hCacheWnd { nullptr }; + HGDIOBJ m_hURLBarFont { nullptr }; + // WKPageConfigurationRef retains page and WebKitBrowserWindow retains page via view + // make sure view is deleted after the page. + std::unique_ptr m_browserWindow; + WKRetainPtr m_configuration; + int m_toolbarItemsWidth { }; +}; diff --git a/browser_patches/webkit/src/Tools/Playwright/win/Playwright.ico b/browser_patches/webkit/src/Tools/Playwright/win/Playwright.ico new file mode 100644 index 0000000000..0137fe83a5 Binary files /dev/null and b/browser_patches/webkit/src/Tools/Playwright/win/Playwright.ico differ diff --git a/browser_patches/webkit/src/Tools/Playwright/win/Playwright.rc b/browser_patches/webkit/src/Tools/Playwright/win/Playwright.rc new file mode 100644 index 0000000000..4430f19062 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/Playwright.rc @@ -0,0 +1,76 @@ +// Microsoft Visual C++ generated resource script. +// +#include "PlaywrightResource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_PLAYWRIGHT ICON "Playwright.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "PlaywrightResource.\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLib.rc b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLib.rc new file mode 100644 index 0000000000..83039d330f --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLib.rc @@ -0,0 +1,354 @@ +// Microsoft Visual C++ generated resource script. +// +#include "PlaywrightLibResource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_PLAYWRIGHT ICON "Playwright.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDC_PLAYWRIGHT MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "New Window\tCtrl-N" IDM_NEW_WINDOW + MENUITEM "Close\tCtrl-W", IDM_CLOSE_WINDOW + END + POPUP "&View" + BEGIN + MENUITEM "Actual Size\tCtrl+0", IDM_ACTUAL_SIZE + MENUITEM "Zoom In\tCtrl++", IDM_ZOOM_IN + MENUITEM "Zoom Out\tCtrl+-", IDM_ZOOM_OUT + MENUITEM "Invert Colors", IDM_INVERT_COLORS + END + POPUP "&History" + BEGIN + MENUITEM "Reload\tCtrl-R", IDM_RELOAD + MENUITEM "Back", IDM_HISTORY_BACKWARD + MENUITEM "Forward", IDM_HISTORY_FORWARD + END + POPUP "D&evelop" + BEGIN + MENUITEM "Show Web Inspector", IDM_WEB_INSPECTOR + END + POPUP "&Help" + BEGIN + MENUITEM "&About ...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_PLAYWRIGHT ACCELERATORS +BEGIN + "/", IDM_ABOUT, ASCII, ALT, NOINVERT + "0", IDM_ACTUAL_SIZE, VIRTKEY, CONTROL, NOINVERT + "?", IDM_ABOUT, ASCII, ALT, NOINVERT + "R", IDM_RELOAD, VIRTKEY, CONTROL, NOINVERT + "N", IDM_NEW_WINDOW, VIRTKEY, CONTROL, NOINVERT + VK_ADD, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT + VK_OEM_MINUS, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT + VK_OEM_PLUS, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT + VK_SUBTRACT, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT +END + +IDR_ACCELERATORS_PRE ACCELERATORS +BEGIN + "W", IDM_CLOSE_WINDOW, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 22, 17, 230, 41 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + ICON IDI_PLAYWRIGHT,IDC_MYICON,14,9,20,20 + LTEXT "Playwright Version 1.1",IDC_STATIC,49,10,119,8 + LTEXT "Copyright (C) 2015-2019",IDC_STATIC,49,20,119,8 + DEFPUSHBUTTON "OK",IDOK,186,10,30,11,WS_GROUP +END + +IDD_CACHES DIALOGEX 0, 0, 401, 456 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,287,435,50,14 + PUSHBUTTON "Cancel",IDCANCEL,344,435,50,14 + GROUPBOX "FastMalloc",IDC_STATIC,208,14,186,67 + GROUPBOX "WebCore Cache",IDC_STATIC,17,83,376,105 + GROUPBOX "JavaScript Heap",IDC_STATIC,18,193,376,168 + GROUPBOX "Site Icon Database",IDC_STATIC,18,366,142,65 + GROUPBOX "Font and Glyph Caches",IDC_STATIC,168,366,226,66 + GROUPBOX "CFURLCache",IDC_STATIC,7,14,197,67 + PUSHBUTTON "Empty URLCache",IDC_EMPTY_URL_CACHE,131,63,69,14,WS_DISABLED + PUSHBUTTON "Return Free Memory",IDC_RETURN_FREE_MEMORY,308,63,76,14,WS_DISABLED + PUSHBUTTON "Empty WebCore Cache",IDC_EMPTY_WEBCORE_CACHE,21,170,83,14,WS_DISABLED + CONTROL "Disable WebCore Cache",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,119,172,93,10 + PUSHBUTTON "Garbage Collect JavaScript Objects",IDC_GC_JSC,253,343,135,14,WS_DISABLED + RTEXT "Reserved VM",IDC_STATIC,212,26,67,9 + RTEXT "0",IDC_RESERVED_VM,290,26,94,8 + RTEXT "Committed VM",IDC_STATIC,211,39,67,8 + RTEXT "0",IDC_COMMITTED_VM,290,39,94,8 + RTEXT "Free List Bytes",IDC_STATIC,211,52,67,8 + RTEXT "0",IDC_FREE_LIST_BYTES,290,52,94,8 + RTEXT "Images",IDC_STATIC,37,106,24,8 + RTEXT "CSS",IDC_STATIC,47,116,14,8 + RTEXT "XSL",IDC_STATIC,49,126,12,8 + RTEXT "JavaScript",IDC_STATIC,27,135,34,8 + RTEXT "Total",IDC_STATIC,43,146,17,8 + LTEXT "Objects",IDC_STATIC,111,96,26,8 + LTEXT "Bytes",IDC_STATIC,175,96,19,8 + LTEXT "Live",IDC_STATIC,232,96,14,8 + LTEXT "Decoded",IDC_STATIC,284,96,29,8 + LTEXT "Purgeable",IDC_STATIC,351,96,33,8 + RTEXT "0",IDC_IMAGES_OBJECT_COUNT,100,106,32,8 + RTEXT "0",IDC_CSS_OBJECT_COUNT,100,116,32,8 + RTEXT "0",IDC_XSL_OBJECT_COUNT,100,126,32,8 + RTEXT "0",IDC_JSC_OBJECT_COUNT,100,135,32,8 + RTEXT "0",IDC_TOTAL_OBJECT_COUNT,100,146,32,8 + RTEXT "0",IDC_IMAGES_BYTES,162,106,32,8 + RTEXT "0",IDC_CSS_BYTES,162,116,32,8 + RTEXT "0",IDC_XSL_BYTES,162,126,32,8 + RTEXT "0",IDC_JSC_BYTES,162,135,32,8 + RTEXT "0",IDC_TOTAL_BYTES,162,146,32,8 + RTEXT "0",IDC_IMAGES_LIVE_COUNT,221,106,32,8 + RTEXT "0",IDC_CSS_LIVE_COUNT,221,116,32,8 + RTEXT "0",IDC_XSL_LIVE_COUNT,221,126,32,8 + RTEXT "0",IDC_JSC_LIVE_COUNT,221,135,32,8 + RTEXT "0",IDC_TOTAL_LIVE_COUNT,221,146,32,8 + RTEXT "0",IDC_IMAGES_DECODED_COUNT,284,106,32,8 + RTEXT "0",IDC_CSS_DECODED_COUNT,284,116,32,8 + RTEXT "0",IDC_XSL_DECODED_COUNT,284,126,32,8 + RTEXT "0",IDC_JSC_DECODED_COUNT,284,135,32,8 + RTEXT "0",IDC_TOTAL_DECODED,284,146,32,8 + RTEXT "0",IDC_IMAGES_PURGEABLE_COUNT,354,106,32,8 + RTEXT "0",IDC_CSS_PURGEABLE_COUNT,354,116,32,8 + RTEXT "0",IDC_XSL_PURGEABLE_COUNT,354,126,32,8 + RTEXT "0",IDC_JSC_PURGEABLE_COUNT,354,135,32,8 + RTEXT "0",IDC_TOTAL_PURGEABLE,354,146,32,8 + RTEXT "Total Objects",IDC_STATIC,63,207,44,8 + RTEXT "Global Objects",IDC_STATIC,56,217,51,8 + RTEXT "Protected Objects",IDC_STATIC,48,227,59,8 + RTEXT "0",IDC_TOTAL_JSC_HEAP_OBJECTS,127,207,56,8 + RTEXT "0",IDC_GLOBAL_JSC_HEAP_OBJECTS,127,217,56,8 + RTEXT "0",IDC_PROTECTED_JSC_HEAP_OBJECTS,127,227,56,8 + RTEXT "Size",IDC_STATIC56,223,207,14,8 + RTEXT "Free",IDC_STATIC57,222,217,16,8 + RTEXT "0",IDC_JSC_HEAP_SIZE,270,207,56,8 + RTEXT "0",IDC_JSC_HEAP_FREE,270,217,56,8 + PUSHBUTTON "Purge Inactive Font Data",IDC_BUTTON5,293,415,95,14,WS_DISABLED + LTEXT "Total Font Data Objects",IDC_STATIC,208,379,78,8 + LTEXT "Inactive Font Data Objects",IDC_STATIC,198,390,88,8 + LTEXT "Glyph Pages",IDC_STATIC,246,402,40,8 + RTEXT "0",IDC_TOTAL_FONT_OBJECTS,329,379,56,8 + RTEXT "0",IDC_INACTIVE_FONT_OBJECTS,329,390,56,8 + RTEXT "0",IDC_GLYPH_PAGES,329,402,56,8 + LTEXT "Page URL Mappings",IDC_STATIC,33,380,64,8 + LTEXT "Retained Page URLs",IDC_STATIC,31,390,66,8 + LTEXT "Site Icon Records",IDC_STATIC,40,400,57,8 + LTEXT "Site Icons with Data",IDC_STATIC,32,410,65,8 + RTEXT "0",IDC_PAGE_URL_MAPPINGS,101,380,52,8 + RTEXT "0",IDC_RETAINED_PAGE_URLS,101,390,52,8 + RTEXT "0",IDC_SITE_ICON_RECORDS,101,400,52,8 + RTEXT "0",IDC_SITE_ICONS_WITH_DATA,101,410,52,8 +END + +IDD_AUTH DIALOGEX 0, 0, 231, 119 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Authentication Required" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Sign In",IDOK,116,98,50,14 + PUSHBUTTON "Cancel",IDCANCEL,174,98,50,14 + LTEXT "Realm",IDC_REALM_TEXT,67,21,157,8 + RTEXT "User Name:",IDC_STATIC,7,41,57,8 + EDITTEXT IDC_AUTH_USER,67,39,157,14,ES_AUTOHSCROLL + RTEXT "Password:",IDC_STATIC,7,66,57,8 + EDITTEXT IDC_AUTH_PASSWORD,67,64,157,14,ES_PASSWORD | ES_AUTOHSCROLL +END + +IDD_PROXY DIALOGEX 0, 0, 310, 176 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Proxy Configuration" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,199,155,50,14 + PUSHBUTTON "Cancel",IDCANCEL,253,155,50,14 + CONTROL "Use system default proxy configuration.",IDC_PROXY_DEFAULT, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,22,15,226,10 + CONTROL "Use custom proxy configuration:",IDC_PROXY_CUSTOM, + "Button",BS_AUTORADIOBUTTON,22,33,226,10 + CONTROL "Don't use proxy.",IDC_PROXY_DISABLE,"Button",BS_AUTORADIOBUTTON,22,117,226,10 + EDITTEXT IDC_PROXY_URL,76,52,193,14,ES_AUTOHSCROLL + EDITTEXT IDC_PROXY_EXCLUDE,76,85,193,14,ES_AUTOHSCROLL + LTEXT "URL:",IDC_STATIC,30,55,43,8,0,WS_EX_RIGHT + LTEXT "Excude list:",IDC_STATIC,30,88,43,8,0,WS_EX_RIGHT + LTEXT "Example: http://192.168.0.2:8000",IDC_STATIC,80,68,194,8 + LTEXT "Comma separated hostnames.",IDC_STATIC,80,101,194,8 +END + +IDD_SERVER_TRUST DIALOGEX 0, 0, 319, 184 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Server Trust Evaluation Request" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Yes",IDOK,197,163,50,14 + PUSHBUTTON "No",IDCANCEL,262,163,50,14 + LTEXT "Certificate information",IDC_STATIC,7,7,294,17 + EDITTEXT IDC_SERVER_TRUST_TEXT,7,24,305,130,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "PlaywrightLibResource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + END + + IDD_CACHES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 394 + TOPMARGIN, 7 + BOTTOMMARGIN, 449 + END + + IDD_AUTH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 224 + VERTGUIDE, 64 + VERTGUIDE, 67 + TOPMARGIN, 7 + BOTTOMMARGIN, 92 + HORZGUIDE, 25 + HORZGUIDE, 50 + END + + IDD_PROXY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 303 + VERTGUIDE, 22 + TOPMARGIN, 7 + BOTTOMMARGIN, 169 + END + + IDD_SERVER_TRUST, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 312 + TOPMARGIN, 7 + BOTTOMMARGIN, 177 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TOOLBAR BITMAP "toolbar.bmp" + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "Playwright" + IDC_PLAYWRIGHT "Playwright" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLibResource.h b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLibResource.h new file mode 100644 index 0000000000..360c0a9cec --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightLibResource.h @@ -0,0 +1,115 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PlaywrightLib.rc +// +#define IDC_MYICON 2 +#define IDD_PLAYWRIGHT_DIALOG 102 +#define IDS_APP_TITLE 103 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDI_PLAYWRIGHT 107 +#define IDC_PLAYWRIGHT 109 +#define IDM_WEB_INSPECTOR 120 +#define IDM_INVERT_COLORS 125 +#define IDR_MAINFRAME 128 +#define IDD_CACHES 129 +#define IDM_HISTORY_BACKWARD 130 +#define IDD_USER_AGENT 130 +#define IDM_HISTORY_FORWARD 131 +#define IDM_HISTORY_LINK0 150 +#define IDM_HISTORY_LINK1 151 +#define IDM_HISTORY_LINK2 152 +#define IDM_HISTORY_LINK3 153 +#define IDM_HISTORY_LINK4 154 +#define IDM_HISTORY_LINK5 155 +#define IDM_HISTORY_LINK6 156 +#define IDM_HISTORY_LINK7 157 +#define IDM_HISTORY_LINK8 158 +#define IDM_HISTORY_LINK9 159 +#define IDT_UPDATE_STATS 160 +#define IDM_ACTUAL_SIZE 172 +#define IDM_ZOOM_IN 173 +#define IDM_ZOOM_OUT 174 +#define IDD_AUTH 176 +#define IDD_PROXY 178 +#define IDD_SERVER_TRUST 179 +#define IDR_ACCELERATORS_PRE 180 +#define IDB_TOOLBAR 181 +#define IDC_EMPTY_URL_CACHE 1000 +#define IDC_RETURN_FREE_MEMORY 1001 +#define IDC_EMPTY_WEBCORE_CACHE 1002 +#define IDC_CHECK1 1003 +#define IDC_HEAP_OBJECTS 1005 +#define IDC_GC_JSC 1006 +#define IDC_RESERVED_VM 1007 +#define IDC_COMMITTED_VM 1008 +#define IDC_FREE_LIST_BYTES 1009 +#define IDC_IMAGES_OBJECT_COUNT 1011 +#define IDC_CSS_OBJECT_COUNT 1012 +#define IDC_XSL_OBJECT_COUNT 1013 +#define IDC_JSC_OBJECT_COUNT 1014 +#define IDC_TOTAL_OBJECT_COUNT 1015 +#define IDC_IMAGES_BYTES 1016 +#define IDC_CSS_BYTES 1017 +#define IDC_XSL_BYTES 1018 +#define IDC_JSC_BYTES 1019 +#define IDC_TOTAL_BYTES 1020 +#define IDC_IMAGES_LIVE_COUNT 1021 +#define IDC_CSS_LIVE_COUNT 1022 +#define IDC_XSL_LIVE_COUNT 1023 +#define IDC_JSC_LIVE_COUNT 1024 +#define IDC_TOTAL_LIVE_COUNT 1025 +#define IDC_IMAGES_DECODED_COUNT 1026 +#define IDC_CSS_DECODED_COUNT 1027 +#define IDC_XSL_DECODED_COUNT 1028 +#define IDC_JSC_DECODED_COUNT 1029 +#define IDC_TOTAL_DECODED 1030 +#define IDC_IMAGES_PURGEABLE_COUNT 1031 +#define IDC_CSS_PURGEABLE_COUNT 1032 +#define IDC_XSL_PURGEABLE_COUNT 1033 +#define IDC_JSC_PURGEABLE_COUNT 1034 +#define IDC_TOTAL_PURGEABLE 1035 +#define IDC_TOTAL_JSC_HEAP_OBJECTS 1036 +#define IDC_GLOBAL_JSC_HEAP_OBJECTS 1037 +#define IDC_PROTECTED_JSC_HEAP_OBJECTS 1038 +#define IDC_STATIC56 1039 +#define IDC_STATIC57 1040 +#define IDC_JSC_HEAP_SIZE 1041 +#define IDC_JSC_HEAP_FREE 1042 +#define IDC_BUTTON5 1043 +#define IDC_TOTAL_FONT_OBJECTS 1044 +#define IDC_Message 1044 +#define IDC_INACTIVE_FONT_OBJECTS 1045 +#define IDC_GLYPH_PAGES 1046 +#define IDC_PAGE_URL_MAPPINGS 1047 +#define IDC_RETAINED_PAGE_URLS 1048 +#define IDC_SITE_ICON_RECORDS 1049 +#define IDC_TOTAL_FONT_OBJECTS5 1050 +#define IDC_SITE_ICONS_WITH_DATA 1051 +#define IDC_USER_AGENT_INPUT 1052 +#define IDC_AUTH_USER 1053 +#define IDC_AUTH_PASSWORD 1054 +#define IDC_URL_BAR 1055 +#define IDC_REALM_TEXT 1056 +#define IDC_PROXY_URL 1057 +#define IDC_PROXY_DEFAULT 1058 +#define IDC_PROXY_CUSTOM 1059 +#define IDC_PROXY_EXCLUDE 1060 +#define IDC_PROXY_DISABLE 1061 +#define IDC_SERVER_TRUST_TEXT 1062 +#define IDM_NEW_WINDOW 32776 +#define IDM_RELOAD 32779 +#define IDM_CLOSE_WINDOW 32780 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 182 +#define _APS_NEXT_COMMAND_VALUE 32783 +#define _APS_NEXT_CONTROL_VALUE 1063 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightReplace.h b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightReplace.h new file mode 100644 index 0000000000..dd134b879e --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightReplace.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Alex Christensen. 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. + */ + +#pragma once + +// This file is to make it easier for users to manage changes to the internals of Playwright + +static void processCrashReport(const wchar_t* fileName) { ::MessageBox(0, fileName, L"Crash Report", MB_OK); } diff --git a/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightResource.h b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightResource.h new file mode 100644 index 0000000000..c60d7b73f1 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/PlaywrightResource.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PlaywrightLauncher.rc +// +#define IDD_PLAYWRIGHT_DIALOG 102 +#define IDI_PLAYWRIGHT 107 +#define IDR_MAINFRAME 128 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.cpp b/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.cpp new file mode 100644 index 0000000000..97e736dd12 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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 "stdafx.h" +#include "Common.h" +#include "MainWindow.h" +#include "PlaywrightLibResource.h" +#include "WebKitBrowserWindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +std::wstring createPEMString(WKCertificateInfoRef certificateInfo) +{ + auto chainSize = WKCertificateInfoGetCertificateChainSize(certificateInfo); + + std::wstring pems; + + for (auto i = 0; i < chainSize; i++) { + auto certificate = adoptWK(WKCertificateInfoCopyCertificateAtIndex(certificateInfo, i)); + auto size = WKDataGetSize(certificate.get()); + auto data = WKDataGetBytes(certificate.get()); + + for (size_t i = 0; i < size; i++) + pems.push_back(data[i]); + } + + return replaceString(pems, L"\n", L"\r\n"); +} + +WebKitBrowserWindow::WebKitBrowserWindow(BrowserWindowClient& client, HWND mainWnd, WKPageConfigurationRef conf) + : m_client(client) + , m_hMainWnd(mainWnd) +{ + RECT rect = { }; + m_view = adoptWK(WKViewCreate(rect, conf, mainWnd)); + WKViewSetIsInWindow(m_view.get(), true); + + auto page = WKViewGetPage(m_view.get()); + + WKPageNavigationClientV0 navigationClient = { }; + navigationClient.base.version = 0; + navigationClient.base.clientInfo = this; + navigationClient.didReceiveAuthenticationChallenge = didReceiveAuthenticationChallenge; + WKPageSetPageNavigationClient(page, &navigationClient.base); + + WKPageUIClientV14 uiClient = { }; + uiClient.base.version = 14; + uiClient.base.clientInfo = this; + uiClient.createNewPage = createNewPage; + uiClient.didNotHandleKeyEvent = didNotHandleKeyEvent; + uiClient.close = closeWindow; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + uiClient.runJavaScriptConfirm = runJavaScriptConfirm; + uiClient.runJavaScriptPrompt = runJavaScriptPrompt; + uiClient.runBeforeUnloadConfirmPanel = runBeforeUnloadConfirmPanel; + uiClient.handleJavaScriptDialog = handleJavaScriptDialog; + WKPageSetPageUIClient(page, &uiClient.base); + + WKPageStateClientV0 stateClient = { }; + stateClient.base.version = 0; + stateClient.base.clientInfo = this; + stateClient.didChangeTitle = didChangeTitle; + stateClient.didChangeIsLoading = didChangeIsLoading; + stateClient.didChangeActiveURL = didChangeActiveURL; + WKPageSetPageStateClient(page, &stateClient.base); + + WKPagePolicyClientV1 policyClient = { }; + policyClient.base.version = 1; + policyClient.base.clientInfo = this; + policyClient.decidePolicyForResponse_deprecatedForUseWithV0 = decidePolicyForResponse; + WKPageSetPagePolicyClient(page, &policyClient.base); + resetZoom(); +} + +WebKitBrowserWindow::~WebKitBrowserWindow() +{ + if (m_alertDialog) { + WKRelease(m_alertDialog); + m_alertDialog = NULL; + } + + if (m_confirmDialog) { + WKRelease(m_confirmDialog); + m_confirmDialog = NULL; + } + + if (m_promptDialog) { + WKRelease(m_promptDialog); + m_promptDialog = NULL; + } + + if (m_beforeUnloadDialog) { + WKRelease(m_beforeUnloadDialog); + m_beforeUnloadDialog = NULL; + } +} + +HWND WebKitBrowserWindow::hwnd() +{ + return WKViewGetWindow(m_view.get()); +} + +HRESULT WebKitBrowserWindow::loadURL(const BSTR& url) +{ + auto page = WKViewGetPage(m_view.get()); + WKPageLoadURL(page, createWKURL(_bstr_t(url)).get()); + return true; +} + +void WebKitBrowserWindow::reload() +{ + auto page = WKViewGetPage(m_view.get()); + WKPageReload(page); +} + +void WebKitBrowserWindow::navigateForwardOrBackward(bool forward) +{ + auto page = WKViewGetPage(m_view.get()); + if (forward) + WKPageGoForward(page); + else + WKPageGoBack(page); +} + +void WebKitBrowserWindow::launchInspector() +{ + auto page = WKViewGetPage(m_view.get()); + auto inspector = WKPageGetInspector(page); + WKInspectorShow(inspector); +} + +void WebKitBrowserWindow::setUserAgent(_bstr_t& customUAString) +{ + auto page = WKViewGetPage(m_view.get()); + auto ua = createWKString(customUAString); + WKPageSetCustomUserAgent(page, ua.get()); +} + +_bstr_t WebKitBrowserWindow::userAgent() +{ + auto page = WKViewGetPage(m_view.get()); + auto ua = adoptWK(WKPageCopyUserAgent(page)); + return createString(ua.get()).c_str(); +} + +void WebKitBrowserWindow::resetZoom() +{ + auto page = WKViewGetPage(m_view.get()); + WKPageSetPageZoomFactor(page, WebCore::deviceScaleFactorForWindow(hwnd())); +} + +void WebKitBrowserWindow::zoomIn() +{ + auto page = WKViewGetPage(m_view.get()); + double s = WKPageGetPageZoomFactor(page); + WKPageSetPageZoomFactor(page, s * 1.25); +} + +void WebKitBrowserWindow::zoomOut() +{ + auto page = WKViewGetPage(m_view.get()); + double s = WKPageGetPageZoomFactor(page); + WKPageSetPageZoomFactor(page, s * 0.8); +} + +static WebKitBrowserWindow& toWebKitBrowserWindow(const void *clientInfo) +{ + return *const_cast(static_cast(clientInfo)); +} + +void WebKitBrowserWindow::didChangeTitle(const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + auto page = WKViewGetPage(thisWindow.m_view.get()); + WKRetainPtr title = adoptWK(WKPageCopyTitle(page)); + std::wstring titleString = createString(title.get()) + L" [WebKit]"; + SetWindowText(thisWindow.m_hMainWnd, titleString.c_str()); +} + +void WebKitBrowserWindow::didChangeIsLoading(const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); +} + +void WebKitBrowserWindow::didChangeActiveURL(const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + auto page = WKViewGetPage(thisWindow.m_view.get()); + WKRetainPtr url = adoptWK(WKPageCopyActiveURL(page)); + thisWindow.m_client.activeURLChanged(createString(url.get())); +} + +void WebKitBrowserWindow::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef challenge, const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + auto protectionSpace = WKAuthenticationChallengeGetProtectionSpace(challenge); + auto decisionListener = WKAuthenticationChallengeGetDecisionListener(challenge); + auto authenticationScheme = WKProtectionSpaceGetAuthenticationScheme(protectionSpace); + + if (authenticationScheme == kWKProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) { + if (thisWindow.canTrustServerCertificate(protectionSpace)) { + WKRetainPtr username = createWKString("accept server trust"); + WKRetainPtr password = createWKString(""); + WKRetainPtr wkCredential = adoptWK(WKCredentialCreate(username.get(), password.get(), kWKCredentialPersistenceForSession)); + WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get()); + return; + } + } else { + WKRetainPtr realm(WKProtectionSpaceCopyRealm(protectionSpace)); + + if (auto credential = askCredential(thisWindow.hwnd(), createString(realm.get()))) { + WKRetainPtr username = createWKString(credential->username); + WKRetainPtr password = createWKString(credential->password); + WKRetainPtr wkCredential = adoptWK(WKCredentialCreate(username.get(), password.get(), kWKCredentialPersistenceForSession)); + WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get()); + return; + } + } + + WKAuthenticationDecisionListenerUseCredential(decisionListener, nullptr); +} + +bool WebKitBrowserWindow::canTrustServerCertificate(WKProtectionSpaceRef protectionSpace) +{ + auto host = createString(adoptWK(WKProtectionSpaceCopyHost(protectionSpace)).get()); + auto certificateInfo = adoptWK(WKProtectionSpaceCopyCertificateInfo(protectionSpace)); + auto verificationError = WKCertificateInfoGetVerificationError(certificateInfo.get()); + auto description = createString(adoptWK(WKCertificateInfoCopyVerificationErrorDescription(certificateInfo.get())).get()); + auto pem = createPEMString(certificateInfo.get()); + + auto it = m_acceptedServerTrustCerts.find(host); + if (it != m_acceptedServerTrustCerts.end() && it->second == pem) + return true; + + std::wstring textString = L"[HOST] " + host + L"\r\n"; + textString.append(L"[ERROR] " + std::to_wstring(verificationError) + L"\r\n"); + textString.append(L"[DESCRIPTION] " + description + L"\r\n"); + textString.append(pem); + + if (askServerTrustEvaluation(hwnd(), textString)) { + m_acceptedServerTrustCerts.emplace(host, pem); + return true; + } + + return false; +} + +void WebKitBrowserWindow::closeWindow(WKPageRef page, const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + PostMessage(thisWindow.m_hMainWnd, WM_CLOSE, 0, 0); +} + +void WebKitBrowserWindow::runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + WKRetain(listener); + thisWindow.m_alertDialog = listener; +} + +void WebKitBrowserWindow::runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + WKRetain(listener); + thisWindow.m_confirmDialog = listener; +} + +void WebKitBrowserWindow::runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + WKRetain(listener); + thisWindow.m_promptDialog = listener; +} + +void WebKitBrowserWindow::runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + WKRetain(listener); + thisWindow.m_beforeUnloadDialog = listener; +} + +void WebKitBrowserWindow::handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + if (thisWindow.m_alertDialog) { + WKPageRunJavaScriptAlertResultListenerCall(thisWindow.m_alertDialog); + WKRelease(thisWindow.m_alertDialog); + thisWindow.m_alertDialog = NULL; + } + + if (thisWindow.m_confirmDialog) { + WKPageRunJavaScriptConfirmResultListenerCall(thisWindow.m_confirmDialog, accept); + WKRelease(thisWindow.m_confirmDialog); + thisWindow.m_confirmDialog = NULL; + } + + if (thisWindow.m_promptDialog) { + WKPageRunJavaScriptPromptResultListenerCall(thisWindow.m_promptDialog, accept ? value : NULL); + WKRelease(thisWindow.m_promptDialog); + thisWindow.m_promptDialog = NULL; + } + + if (thisWindow.m_beforeUnloadDialog) { + WKPageRunBeforeUnloadConfirmPanelResultListenerCall(thisWindow.m_beforeUnloadDialog, accept); + WKRelease(thisWindow.m_beforeUnloadDialog); + thisWindow.m_beforeUnloadDialog = NULL; + } +} + +WKPageRef WebKitBrowserWindow::createPageCallback(WKPageConfigurationRef configuration) +{ + return WebKitBrowserWindow::createViewCallback(configuration, true); +} + +WKPageRef WebKitBrowserWindow::createViewCallback(WKPageConfigurationRef configuration, bool navigate) +{ + auto* newWindow = new MainWindow(); + bool ok = newWindow->init(hInst, configuration); + if (navigate) + newWindow->browserWindow()->loadURL(_bstr_t("about:blank").GetBSTR()); + + auto* newBrowserWindow = newWindow->browserWindow(); + return WKViewGetPage(newBrowserWindow->m_view.get()); +} + + +WKPageRef WebKitBrowserWindow::createNewPage(WKPageRef, WKPageConfigurationRef configuration, WKNavigationActionRef, WKWindowFeaturesRef, const void*) +{ + // Retain popups as per API contract. + WKRetainPtr newPage = createViewCallback(configuration, false); + return newPage.leakRef(); +} + +void WebKitBrowserWindow::didNotHandleKeyEvent(WKPageRef, WKNativeEventPtr event, const void* clientInfo) +{ + auto& thisWindow = toWebKitBrowserWindow(clientInfo); + PostMessage(thisWindow.m_hMainWnd, event->message, event->wParam, event->lParam); +} + +void WebKitBrowserWindow::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) +{ + if (WKURLResponseIsAttachment(response)) + WKFramePolicyListenerDownload(listener); + else + WKFramePolicyListenerUse(listener); +} diff --git a/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.h b/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.h new file mode 100644 index 0000000000..36a8e2c6ea --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/WebKitBrowserWindow.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * 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. ``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 + * 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. + */ +#pragma once + +#include "Common.h" +#include +#include +#include + +class BrowserWindowClient { +public: + virtual void activeURLChanged(std::wstring) = 0; +}; + +class WebKitBrowserWindow { +public: + static WKPageRef createPageCallback(WKPageConfigurationRef); + WebKitBrowserWindow(BrowserWindowClient&, HWND mainWnd, WKPageConfigurationRef); + ~WebKitBrowserWindow(); + + HRESULT loadURL(const BSTR& url); + void reload(); + void navigateForwardOrBackward(bool forward); + void launchInspector(); + + _bstr_t userAgent(); + void setUserAgent(_bstr_t&); + + void resetZoom(); + void zoomIn(); + void zoomOut(); + + bool canTrustServerCertificate(WKProtectionSpaceRef); + HWND hwnd(); + +private: + static WKPageRef createViewCallback(WKPageConfigurationRef, bool navigate); + + static void didChangeTitle(const void*); + static void didChangeIsLoading(const void*); + static void didChangeEstimatedProgress(const void*); + static void didChangeActiveURL(const void*); + static void didReceiveAuthenticationChallenge(WKPageRef, WKAuthenticationChallengeRef, const void*); + static WKPageRef createNewPage(WKPageRef, WKPageConfigurationRef, WKNavigationActionRef, WKWindowFeaturesRef, const void *); + static void closeWindow(WKPageRef, const void*); + static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo); + static void runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo); + static void runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo); + static void runBeforeUnloadConfirmPanel(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo); + static void handleJavaScriptDialog(WKPageRef page, bool accept, WKStringRef value, const void *clientInfo); + static void didNotHandleKeyEvent(WKPageRef, WKNativeEventPtr, const void*); + static void decidePolicyForResponse(WKPageRef, WKFrameRef, WKURLResponseRef, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef, const void*); + + BrowserWindowClient& m_client; + WKRetainPtr m_view; + HWND m_hMainWnd { nullptr }; + ProxySettings m_proxy { }; + std::unordered_map m_acceptedServerTrustCerts; + WKPageRunJavaScriptAlertResultListenerRef m_alertDialog = { }; + WKPageRunJavaScriptConfirmResultListenerRef m_confirmDialog = { }; + WKPageRunJavaScriptPromptResultListenerRef m_promptDialog = { }; + WKPageRunBeforeUnloadConfirmPanelResultListenerRef m_beforeUnloadDialog = { }; +}; diff --git a/browser_patches/webkit/src/Tools/Playwright/win/WinMain.cpp b/browser_patches/webkit/src/Tools/Playwright/win/WinMain.cpp new file mode 100644 index 0000000000..2cf6cfe710 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/WinMain.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2006, 2008, 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2011 Brent Fulgham. All rights reserved. + * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved. + * Copyright (C) 2013 Alex Christensen. 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. ``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 + * 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. + */ + +#pragma warning(disable: 4091) + +#include "stdafx.h" +#include "Common.h" +#include "MainWindow.h" +#include "PlaywrightLibResource.h" +#include "PlaywrightReplace.h" +#include +#include +#include +#include +#include "WebKitBrowserWindow.h" +#include +#include + +SOFT_LINK_LIBRARY(user32); +SOFT_LINK_OPTIONAL(user32, SetProcessDpiAwarenessContext, BOOL, STDAPICALLTYPE, (DPI_AWARENESS_CONTEXT)); + +WKRetainPtr toWK(const std::string& string) +{ + return adoptWK(WKStringCreateWithUTF8CString(string.c_str())); +} + +std::string toUTF8String(const wchar_t* src, size_t srcLength) +{ + int length = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, 0, 0, nullptr, nullptr); + std::vector buffer(length); + size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr); + return { buffer.data(), actualLength }; +} + +int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpstrCmdLine, _In_ int nCmdShow) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); +#endif + + MSG msg { }; + HACCEL hAccelTable, hPreAccelTable; + + INITCOMMONCONTROLSEX InitCtrlEx; + + InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCtrlEx.dwICC = 0x00004000; // ICC_STANDARD_CLASSES; + InitCommonControlsEx(&InitCtrlEx); + + auto options = parseCommandLine(); + if (options.inspectorPipe) { + WKInspectorInitializeRemoteInspectorPipe( + WebKitBrowserWindow::createPageCallback, + []() { PostQuitMessage(0); }); + } + + if (options.useFullDesktop) + computeFullDesktopFrame(); + + // Init COM + OleInitialize(nullptr); + + if (SetProcessDpiAwarenessContextPtr()) + SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE); + + MainWindow::configure(options.headless, options.noStartupWindow); + + if (!options.noStartupWindow) { + auto configuration = adoptWK(WKWebsiteDataStoreConfigurationCreate()); + if (options.userDataDir.length()) { + std::string profileFolder = toUTF8String(options.userDataDir, options.userDataDir.length()); + WKWebsiteDataStoreConfigurationSetApplicationCacheDirectory(configuration.get(), toWK(profileFolder + "\\ApplicationCache").get()); + WKWebsiteDataStoreConfigurationSetNetworkCacheDirectory(configuration.get(), toWK(profileFolder + "\\Cache").get()); + WKWebsiteDataStoreConfigurationSetCacheStorageDirectory(configuration.get(), toWK(profileFolder + "\\CacheStorage").get()); + WKWebsiteDataStoreConfigurationSetIndexedDBDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\IndexedDB").get()); + WKWebsiteDataStoreConfigurationSetLocalStorageDirectory(configuration.get(), toWK(profileFolder + "\\LocalStorage").get()); + WKWebsiteDataStoreConfigurationSetWebSQLDatabaseDirectory(configuration.get(), toWK(profileFolder + "\\Databases" + "\\WebSQL").get()); + WKWebsiteDataStoreConfigurationSetMediaKeysStorageDirectory(configuration.get(), toWK(profileFolder + "\\MediaKeys").get()); + WKWebsiteDataStoreConfigurationSetResourceLoadStatisticsDirectory(configuration.get(), toWK(profileFolder + "\\ResourceLoadStatistics").get()); + WKWebsiteDataStoreConfigurationSetServiceWorkerRegistrationDirectory(configuration.get(), toWK(profileFolder + "\\ServiceWorkers").get()); + } + auto context = adoptWK(WKContextCreateWithConfiguration(nullptr)); + auto dataStore = adoptWK(WKWebsiteDataStoreCreateWithConfiguration(configuration.get())); + WKContextSetPrimaryDataStore(context.get(), dataStore.get()); + + auto* mainWindow = new MainWindow(); + HRESULT hr = mainWindow->init(hInst, context.get(), dataStore.get()); + if (FAILED(hr)) + goto exit; + + if (options.requestedURL.length()) + mainWindow->loadURL(options.requestedURL.GetBSTR()); + else + mainWindow->loadURL(L"about:blank"); + } + + hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_PLAYWRIGHT)); + hPreAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATORS_PRE)); + +#pragma warning(disable:4509) + + // Main message loop: + __try { + while (GetMessage(&msg, nullptr, 0, 0)) { + if (TranslateAccelerator(msg.hwnd, hPreAccelTable, &msg)) + continue; + bool processed = false; + if (MainWindow::isInstance(msg.hwnd)) + processed = TranslateAccelerator(msg.hwnd, hAccelTable, &msg); + if (!processed) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } __except(createCrashReport(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) { } + +exit: +#ifdef _CRTDBG_MAP_ALLOC + _CrtDumpMemoryLeaks(); +#endif + + // Shut down COM. + OleUninitialize(); + + return static_cast(msg.wParam); +} + +extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpstrCmdLine, int nCmdShow) +{ + return wWinMain(hInstance, hPrevInstance, lpstrCmdLine, nCmdShow); +} diff --git a/browser_patches/webkit/src/Tools/Playwright/win/resource.h b/browser_patches/webkit/src/Tools/Playwright/win/resource.h new file mode 100644 index 0000000000..5a19599dae --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/resource.h @@ -0,0 +1,25 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by WinLauncher.rc +// +#define IDC_MYICON 2 +#define IDD_WINLAUNCHER_DIALOG 102 +#define IDS_APP_TITLE 103 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDI_WINLAUNCHER 107 +#define IDC_WINLAUNCHER 109 +#define IDR_MAINFRAME 128 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/browser_patches/webkit/src/Tools/Playwright/win/stdafx.cpp b/browser_patches/webkit/src/Tools/Playwright/win/stdafx.cpp new file mode 100644 index 0000000000..3c4e5e52a1 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/stdafx.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006 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. ``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 + * 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. + */ + +// stdafx.cpp : source file that includes just the standard includes +// Spinneret.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/browser_patches/webkit/src/Tools/Playwright/win/stdafx.h b/browser_patches/webkit/src/Tools/Playwright/win/stdafx.h new file mode 100644 index 0000000000..8436fba636 --- /dev/null +++ b/browser_patches/webkit/src/Tools/Playwright/win/stdafx.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2006 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. ``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 + * 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. + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE) +#include "cmakeconfig.h" +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +// Needed for limit defines, like INTMAX_MAX, which is used by the std C++ library +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if 0 +// Visual Studio Leak Detection +// +#if defined(_MSC_VER) && defined(_DEBUG) +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif +#endif diff --git a/browser_patches/webkit/src/Tools/Playwright/win/toolbar.bmp b/browser_patches/webkit/src/Tools/Playwright/win/toolbar.bmp new file mode 100644 index 0000000000..07eea0dbb5 Binary files /dev/null and b/browser_patches/webkit/src/Tools/Playwright/win/toolbar.bmp differ