browser(webkit): extract webkit embedders into webkit/src (#1919)

This commit is contained in:
Pavel Feldman 2020-04-22 10:52:17 -07:00 committed by GitHub
parent 6ecac8c164
commit 91c0631827
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 5172 additions and 5456 deletions

View File

@ -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"

View File

@ -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 <devops@playwright.com>" -m "chore: bootstrap build #$BUILD_NUMBER"
echo

View File

@ -1 +1 @@
1204
1205

File diff suppressed because it is too large Load Diff

View File

@ -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 = -;

View File

@ -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"

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = "<group>"; };
256AC3D80F4B6AC300CF336A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = mac/AppDelegate.h; sourceTree = "<group>"; };
256AC3D90F4B6AC300CF336A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = mac/AppDelegate.m; sourceTree = "<group>"; };
256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Playwright_Prefix.pch; path = mac/Playwright_Prefix.pch; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEB /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29B97325FDCFA39411CA2CEB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
37BAF90620218053000EA87A /* Playwright.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Playwright.entitlements; sourceTree = "<group>"; };
51E244F811EFCE07008228D2 /* MBToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBToolbarItem.h; sourceTree = "<group>"; };
51E244F911EFCE07008228D2 /* MBToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBToolbarItem.m; sourceTree = "<group>"; };
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 = "<group>"; };
BC329486116A92E2008635D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = mac/main.m; sourceTree = "<group>"; };
BC329496116A941B008635D1 /* BrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserWindowController.h; path = mac/BrowserWindowController.h; sourceTree = "<group>"; };
BC329497116A941B008635D1 /* BrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BrowserWindowController.m; path = mac/BrowserWindowController.m; sourceTree = "<group>"; };
BC3294A2116A9852008635D1 /* BrowserWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = BrowserWindow.xib; path = mac/BrowserWindow.xib; sourceTree = "<group>"; };
BC72B89A11E57E8A001EB4EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = mac/Info.plist; sourceTree = "<group>"; };
BCA8CBDD11E578A000812FB8 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Playwright.xcconfig; sourceTree = "<group>"; };
/* 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 = "<group>";
};
1058C7A2FEA54F0111CA2CBC /* Other Frameworks */ = {
isa = PBXGroup;
children = (
29B97324FDCFA39411CA2CEB /* AppKit.framework */,
1AFFEF781860EE6800DA465F /* CoreData.framework */,
29B97325FDCFA39411CA2CEB /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBC /* Products */ = {
isa = PBXGroup;
children = (
8D1107320486CEB800E47091 /* Playwright.app */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEB /* Playwright */ = {
isa = PBXGroup;
children = (
256AC3F00F4B6AF500CF336A /* Playwright_Prefix.pch */,
080E96DDFE201D6D7F000002 /* Playwright */,
29B97317FDCFA39411CA2CEB /* Resources */,
BCA8CBDA11E5787800812FB8 /* Configurations */,
29B97323FDCFA39411CA2CEB /* Frameworks */,
19C28FACFE9D520D11CA2CBC /* Products */,
);
name = Playwright;
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEB /* Resources */ = {
isa = PBXGroup;
children = (
BC3294A2116A9852008635D1 /* BrowserWindow.xib */,
1DDD58150DA1D0A300B3202A /* MainMenu.xib */,
);
name = Resources;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEB /* Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A2FEA54F0111CA2CBC /* Other Frameworks */,
1AFFEF761860EE6800DA465F /* Cocoa.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
BCA8CBDA11E5787800812FB8 /* Configurations */ = {
isa = PBXGroup;
children = (
BCA8CBDD11E578A000812FB8 /* Base.xcconfig */,
BCA8CBDE11E578A000812FB8 /* DebugRelease.xcconfig */,
BCA8CBDF11E578A000812FB8 /* Playwright.xcconfig */,
A1B89B95221E027A00EB4CEB /* SDKVariant.xcconfig */,
);
path = Configurations;
sourceTree = "<group>";
};
/* 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 */;
}

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "Playwright.app"
BlueprintName = "Playwright"
ReferencedContainer = "container:Playwright.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "Playwright.app"
BlueprintName = "Playwright"
ReferencedContainer = "container:Playwright.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "Playwright.app"
BlueprintName = "Playwright"
ReferencedContainer = "container:Playwright.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -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 <WebKit/_WKBrowserInspector.h>
#import <WebKit/_WKDownloadDelegate.h>
@interface WebViewDialog : NSObject
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, copy) void (^completionHandler)(BOOL accept, NSString* value);
@end
@interface BrowserAppDelegate : NSObject <NSApplicationDelegate, WKNavigationDelegate, WKUIDelegate, _WKBrowserInspectorDelegate, _WKDownloadDelegate> {
NSMutableSet *_headlessWindows;
NSMutableSet *_browserContexts;
bool _headless;
bool _noStartupWindow;
NSMutableSet *_dialogs;
NSString* _initialURL;
NSString* _userDataDir;
IBOutlet NSMenuItem *_newWebKit2WindowItem;
}
@end
@interface NSApplication (PlaywrightApplicationExtensions)
- (BrowserAppDelegate *)browserAppDelegate;
@end

View File

@ -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 <WebKit/WKNavigationActionPrivate.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKUserContentControllerPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/WebNSURLExtras.h>
#import <WebKit/WebKit.h>
#import <WebKit/_WKDownload.h>
#import <WebKit/_WKExperimentalFeature.h>
#import <WebKit/_WKInternalDebugFeature.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
@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

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11191" systemVersion="16D17a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11191"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="BrowserWindowController">
<connections>
<outlet property="backButton" destination="40" id="46"/>
<outlet property="containerView" destination="9" id="37"/>
<outlet property="forwardButton" destination="42" id="47"/>
<outlet property="progressIndicator" destination="21" id="33"/>
<outlet property="reloadButton" destination="23" id="34"/>
<outlet property="share" destination="1hB-AH-eUl" id="si4-8e-DsM"/>
<outlet property="toggleUseShrinkToFitButton" destination="82" id="9w7-AB-Ye3"/>
<outlet property="toolbar" destination="48" id="67"/>
<outlet property="urlText" destination="10" id="32"/>
<outlet property="window" destination="1" id="3"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" frameAutosaveName="Main Window" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES" fullSizeContentView="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="517" y="330" width="776" height="608"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="776" height="608"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView id="9">
<rect key="frame" x="0.0" y="0.0" width="776" height="608"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</customView>
</subviews>
</view>
<toolbar key="toolbar" implicitIdentifier="994A0CB1-7575-4F39-A65B-7165AB1E8015" displayMode="iconOnly" sizeMode="regular" id="48">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="73DE9F4B-73E2-4036-A134-2D9E029DA980" label="Go Back" paletteLabel="Go Back" image="NSGoLeftTemplate" id="56" customClass="MBToolbarItem">
<nil key="toolTip"/>
<size key="minSize" width="32" height="27"/>
<size key="maxSize" width="32" height="25"/>
<button key="view" verticalHuggingPriority="750" id="40">
<rect key="frame" x="10" y="14" width="32" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSGoLeftTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="41">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<connections>
<action selector="goBack:" target="-2" id="61"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="E1A9D32A-59E3-467B-9ABA-A95780416E69" label="Go Forward" paletteLabel="Go Forward" image="NSGoRightTemplate" id="57" customClass="MBToolbarItem">
<nil key="toolTip"/>
<size key="minSize" width="32" height="27"/>
<size key="maxSize" width="32" height="27"/>
<button key="view" verticalHuggingPriority="750" id="42">
<rect key="frame" x="18" y="14" width="32" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSGoRightTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="43">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<connections>
<action selector="goForward:" target="-2" id="62"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="88C16109-D40F-4682-BCE4-CBEE2EDE32D2" label="Refresh" paletteLabel="Refresh" image="NSRefreshTemplate" id="58" customClass="MBToolbarItem">
<nil key="toolTip"/>
<size key="minSize" width="29" height="27"/>
<size key="maxSize" width="29" height="27"/>
<button key="view" verticalHuggingPriority="750" id="23">
<rect key="frame" x="10" y="14" width="29" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSRefreshTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="24">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="reload:" target="-2" id="35"/>
</connections>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="F1738B7F-895C-48F7-955D-0915E150BE1B" label="Share" paletteLabel="Share" image="NSShareTemplate" id="dJx-dw-gcC" customClass="MBToolbarItem">
<nil key="toolTip"/>
<size key="minSize" width="29" height="27"/>
<size key="maxSize" width="29" height="27"/>
<button key="view" verticalHuggingPriority="750" id="1hB-AH-eUl">
<rect key="frame" x="5" y="14" width="29" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSShareTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="S1v-UD-QhI">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<connections>
<action selector="share:" target="-2" id="5e3-hg-bKN"/>
</connections>
</buttonCell>
</button>
</toolbarItem>
<toolbarItem implicitItemIdentifier="255D29F2-C9AA-4B4B-BB43-B38FCD6A0BBB" label="Location" paletteLabel="Location" id="59">
<nil key="toolTip"/>
<size key="minSize" width="200" height="22"/>
<size key="maxSize" width="100000" height="22"/>
<textField key="view" verticalHuggingPriority="750" id="10">
<rect key="frame" x="0.0" y="14" width="565" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="11">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="fetch:" target="-2" id="36"/>
</connections>
</textField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="86912BAA-B8D0-400F-BFEE-71FC166986E6" label="Progress" paletteLabel="Progress" tag="-1" id="60">
<nil key="toolTip"/>
<size key="minSize" width="16" height="16"/>
<size key="maxSize" width="16" height="16"/>
<progressIndicator key="view" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="1" displayedWhenStopped="NO" bezeled="NO" controlSize="small" style="spinning" id="21">
<rect key="frame" x="19" y="14" width="16" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
</progressIndicator>
</toolbarItem>
</allowedToolbarItems>
<defaultToolbarItems>
<toolbarItem reference="56"/>
<toolbarItem reference="57"/>
<toolbarItem reference="58"/>
<toolbarItem reference="59"/>
<toolbarItem reference="60"/>
<toolbarItem reference="dJx-dw-gcC"/>
</defaultToolbarItems>
</toolbar>
<connections>
<outlet property="delegate" destination="-2" id="4"/>
</connections>
</window>
</objects>
<resources>
<image name="NSEnterFullScreenTemplate" width="15" height="15"/>
<image name="NSGoLeftTemplate" width="9" height="12"/>
<image name="NSGoRightTemplate" width="9" height="12"/>
<image name="NSRefreshTemplate" width="11" height="15"/>
<image name="NSShareTemplate" width="11" height="16"/>
</resources>
</document>

View File

@ -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

View File

@ -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 <WebKit/WKFrameInfo.h>
#import <WebKit/WKNavigationActionPrivate.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKUIDelegate.h>
#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WKWebViewPrivateForTesting.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/WebNSURLExtras.h>
#import <WebKit/_WKIconLoadingDelegate.h>
#import <WebKit/_WKInspector.h>
#import <WebKit/_WKLinkIconParameters.h>
#import <WebKit/_WKUserInitiatedAction.h>
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 () <NSTextFinderBarContainer, WKNavigationDelegate, WKUIDelegate, _WKIconLoadingDelegate, NSSharingServicePickerDelegate, NSSharingServiceDelegate>
@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 <NSValidatedUserInterfaceItem>)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<NSURL *> * 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

View File

@ -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)

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>WebKit Browser</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>html</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>text/html</string>
</array>
<key>CFBundleTypeName</key>
<string>HTML</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
</dict>
</plist>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="495"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="Playwright" id="56">
<menu key="submenu" title="Playwright" systemMenu="apple" id="57">
<items>
<menuItem title="About Playwright" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Services" id="131">
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide Playwright" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="145">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
</connections>
</menuItem>
<menuItem title="Show All" id="150">
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit Playwright" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83">
<menu key="submenu" title="File" id="81">
<items>
<menuItem title="Open Location " tag="1" keyEquivalent="l" id="82">
<connections>
<action selector="openLocation:" target="-1" id="575"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="79">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Close" keyEquivalent="w" id="73">
<connections>
<action selector="performClose:" target="-1" id="193"/>
</connections>
</menuItem>
<menuItem title="Save" keyEquivalent="s" id="75">
<connections>
<action selector="saveDocument:" target="-1" id="362"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="80">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="saveDocumentAs:" target="-1" id="363"/>
</connections>
</menuItem>
<menuItem title="Save As PDF…" keyEquivalent="S" id="gmS-3Q-oLs">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="saveAsPDF:" target="-1" id="25T-Id-334"/>
</connections>
</menuItem>
<menuItem title="Save As WebArchive..." id="112">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="saveAsWebArchive:" target="-1" id="AGx-3e-6Nt"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="74">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="-1" id="87"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="78">
<connections>
<action selector="printWebView:" target="-1" id="86"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="217">
<menu key="submenu" title="Edit" id="205">
<items>
<menuItem title="Undo" keyEquivalent="z" id="207">
<connections>
<action selector="undo:" target="-1" id="223"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="215">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="redo:" target="-1" id="231"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="206">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Cut" keyEquivalent="x" id="199">
<connections>
<action selector="cut:" target="-1" id="228"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="197">
<connections>
<action selector="copy:" target="-1" id="224"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="203">
<connections>
<action selector="paste:" target="-1" id="226"/>
</connections>
</menuItem>
<menuItem title="Delete" id="202">
<connections>
<action selector="delete:" target="-1" id="235"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="198">
<connections>
<action selector="selectAll:" target="-1" id="232"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="214">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Find" id="218">
<menu key="submenu" title="Find" id="220">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
<connections>
<action selector="performTextFinderAction:" target="-1" id="241"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
<connections>
<action selector="performTextFinderAction:" target="-1" id="487"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="performTextFinderAction:" target="-1" id="488"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
<connections>
<action selector="performTextFinderAction:" target="-1" id="489"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="295">
<menu key="submenu" title="View" id="296">
<items>
<menuItem title="Zoom In" keyEquivalent="+" id="555">
<connections>
<action selector="zoomIn:" target="-1" id="559"/>
</connections>
</menuItem>
<menuItem title="Zoom Out" keyEquivalent="-" id="557">
<connections>
<action selector="zoomOut:" target="-1" id="560"/>
</connections>
</menuItem>
<menuItem title="Reset Zoom" keyEquivalent="0" id="558">
<connections>
<action selector="resetZoom:" target="-1" id="561"/>
</connections>
</menuItem>
<menuItem title="Zoom Text Only" id="562">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleZoomMode:" target="-1" id="564"/>
</connections>
</menuItem>
<menuItem title="Page Scale" id="Hzb-c3-Qfv">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Page Scale" id="jdo-5V-3CM">
<items>
<menuItem title="100%" state="on" tag="1" keyEquivalent="1" id="wHb-mR-Fv0">
<connections>
<action selector="setPageScale:" target="-1" id="uMw-eY-289"/>
</connections>
</menuItem>
<menuItem title="125%" tag="2" keyEquivalent="2" id="u4i-F7-rPb">
<connections>
<action selector="setPageScale:" target="-1" id="IbE-Ep-hfc"/>
</connections>
</menuItem>
<menuItem title="150%" tag="3" keyEquivalent="3" id="fwT-Iy-oK9">
<connections>
<action selector="setPageScale:" target="-1" id="9c0-eN-0f5"/>
</connections>
</menuItem>
<menuItem title="200%" tag="4" keyEquivalent="4" id="R5e-ct-O2u">
<connections>
<action selector="setPageScale:" target="-1" id="mkk-gh-dlN"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View Scale" id="8UY-Pj-H13">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View Scale" id="Ml8-mk-ffu">
<items>
<menuItem title="100%" state="on" tag="1" id="EAm-Xn-VrC">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setViewScale:" target="-1" id="dkW-CI-RG4"/>
</connections>
</menuItem>
<menuItem title="75%" tag="2" id="jcA-I1-Cbq">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setViewScale:" target="-1" id="BAF-Ym-IqV"/>
</connections>
</menuItem>
<menuItem title="50%" tag="3" id="BRM-D5-YNO">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setViewScale:" target="-1" id="nXy-2b-9Zz"/>
</connections>
</menuItem>
<menuItem title="25%" tag="4" id="gzk-YK-x0W">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setViewScale:" target="-1" id="KXK-f6-24N"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Reload Page" keyEquivalent="r" id="579">
<connections>
<action selector="reload:" target="-1" id="582"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Debug" id="534">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Debug" id="535">
<items>
<menuItem title="Show Web Inspector" keyEquivalent="i" id="xso-9z-R4u">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="showHideWebInspector:" target="-1" id="Cmx-g7-EPb"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="19">
<menu key="submenu" title="Window" systemMenu="window" id="24">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="23">
<connections>
<action selector="performMiniaturize:" target="-1" id="37"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="239">
<connections>
<action selector="performZoom:" target="-1" id="240"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="92">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Bring All to Front" id="5">
<connections>
<action selector="arrangeInFront:" target="-1" id="39"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
<point key="canvasLocation" x="139" y="-50"/>
</menu>
<customObject id="494" customClass="BrowserAppDelegate"/>
</objects>
</document>

View File

@ -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 <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#endif
#define ENABLE_LOGGING 0
#if ENABLE_LOGGING
#define LOG NSLog
#else
#define LOG(...) ((void)0)
#endif

View File

@ -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 <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitLinkedOnOrAfterEverything"];
return NSApplicationMain(argc, (const char **) argv);
}

View File

@ -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)

View File

@ -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 <dbghelp.h>
#include <shlobj.h>
#include <wtf/Optional.h>
#include <wtf/StdLibExtras.h>
#include <vector>
// 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<void*>(&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<const wchar_t*>(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<Credential> 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<WKChar> 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<WKStringRef> 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<char> buffer(length);
size_t actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, buffer.data(), length, nullptr, nullptr);
return { buffer.data(), actualLength };
}
WKRetainPtr<WKStringRef> createWKString(_bstr_t str)
{
auto utf8 = createUTF8String(str, str.length());
return adoptWK(WKStringCreateWithUTF8CString(utf8.data()));
}
WKRetainPtr<WKStringRef> createWKString(const std::wstring& str)
{
auto utf8 = createUTF8String(str.c_str(), str.length());
return adoptWK(WKStringCreateWithUTF8CString(utf8.data()));
}
WKRetainPtr<WKURLRef> createWKURL(_bstr_t str)
{
auto utf8 = createUTF8String(str, str.length());
return adoptWK(WKURLCreateWithUTF8CString(utf8.data()));
}
WKRetainPtr<WKURLRef> createWKURL(const std::wstring& str)
{
auto utf8 = createUTF8String(str.c_str(), str.length());
return adoptWK(WKURLCreateWithUTF8CString(utf8.data()));
}

View File

@ -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 <WebKit/WKRetainPtr.h>
#include <WebKit/WKString.h>
#include <WebKit/WKURL.h>
#include <wtf/Optional.h>
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<Credential> 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<WKStringRef> createWKString(_bstr_t str);
WKRetainPtr<WKStringRef> createWKString(const std::wstring& str);
WKRetainPtr<WKURLRef> createWKURL(_bstr_t str);
WKRetainPtr<WKURLRef> createWKURL(const std::wstring& str);

View File

@ -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 <string>
#include <vector>
class Dialog {
public:
bool run(HINSTANCE hInst, HWND hwnd, int dialogId)
{
auto result = DialogBoxParam(hInst, MAKEINTRESOURCE(dialogId), hwnd, doalogProc, reinterpret_cast<LPARAM>(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<Dialog*>(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<TCHAR> 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 { };
};

View File

@ -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 <sstream>
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<LPARAM>(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<LPARAM>(&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<WNDPROC>(GetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC));
SetWindowLongPtr(m_hURLBarWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(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<LPARAM>(&info));
SendMessage(m_hToolbarWnd, TB_AUTOSIZE, 0, 0);
RECT rect;
SendMessage(m_hToolbarWnd, TB_GETITEMRECT, kToolbarURLBarIndex, reinterpret_cast<LPARAM>(&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<LPARAM>(&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<LPARAM>(&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<MainWindow*>(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<LONG_PTR>(reinterpret_cast<LPCREATESTRUCT>(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<RECT*>(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<UINT>(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<UINT>(WM_SETFONT), reinterpret_cast<WPARAM>(m_hURLBarFont), TRUE);
}
void MainWindow::activeURLChanged(std::wstring url)
{
if (s_headless)
return;
SetWindowText(m_hURLBarWnd, url.c_str());
}

View File

@ -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 <WebKit/WKBase.h>
#include <WebKit/WKRetainPtr.h>
#include <functional>
#include <memory>
#include <string>
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<WebKitBrowserWindow> m_browserWindow;
WKRetainPtr<WKPageConfigurationRef> m_configuration;
int m_toolbarItemsWidth { };
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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); }

View File

@ -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

View File

@ -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 <WebCore/GDIUtilities.h>
#include <WebKit/WKAuthenticationChallenge.h>
#include <WebKit/WKAuthenticationDecisionListener.h>
#include <WebKit/WKCertificateInfoCurl.h>
#include <WebKit/WKCredential.h>
#include <WebKit/WKFramePolicyListener.h>
#include <WebKit/WKInspector.h>
#include <WebKit/WKProtectionSpace.h>
#include <WebKit/WKProtectionSpaceCurl.h>
#include <WebKit/WKWebsiteDataStoreRef.h>
#include <WebKit/WKWebsiteDataStoreRefCurl.h>
#include <vector>
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<WebKitBrowserWindow*>(static_cast<const WebKitBrowserWindow*>(clientInfo));
}
void WebKitBrowserWindow::didChangeTitle(const void* clientInfo)
{
auto& thisWindow = toWebKitBrowserWindow(clientInfo);
auto page = WKViewGetPage(thisWindow.m_view.get());
WKRetainPtr<WKStringRef> 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<WKURLRef> 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<WKStringRef> username = createWKString("accept server trust");
WKRetainPtr<WKStringRef> password = createWKString("");
WKRetainPtr<WKCredentialRef> wkCredential = adoptWK(WKCredentialCreate(username.get(), password.get(), kWKCredentialPersistenceForSession));
WKAuthenticationDecisionListenerUseCredential(decisionListener, wkCredential.get());
return;
}
} else {
WKRetainPtr<WKStringRef> realm(WKProtectionSpaceCopyRealm(protectionSpace));
if (auto credential = askCredential(thisWindow.hwnd(), createString(realm.get()))) {
WKRetainPtr<WKStringRef> username = createWKString(credential->username);
WKRetainPtr<WKStringRef> password = createWKString(credential->password);
WKRetainPtr<WKCredentialRef> 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<WKPageRef> 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);
}

View File

@ -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 <WebKit/WKBase.h>
#include <WebKit/WebKit2_C.h>
#include <unordered_map>
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<WKViewRef> m_view;
HWND m_hMainWnd { nullptr };
ProxySettings m_proxy { };
std::unordered_map<std::wstring, std::wstring> m_acceptedServerTrustCerts;
WKPageRunJavaScriptAlertResultListenerRef m_alertDialog = { };
WKPageRunJavaScriptConfirmResultListenerRef m_confirmDialog = { };
WKPageRunJavaScriptPromptResultListenerRef m_promptDialog = { };
WKPageRunBeforeUnloadConfirmPanelResultListenerRef m_beforeUnloadDialog = { };
};

View File

@ -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 <WebKit/WKContext.h>
#include <WebKit/WKWebsiteDataStoreConfigurationRef.h>
#include <WebKit/WKWebsiteDataStoreRef.h>
#include <wtf/win/SoftLinking.h>
#include "WebKitBrowserWindow.h"
#include <wtf/MainThread.h>
#include <WebKit/WKInspector.h>
SOFT_LINK_LIBRARY(user32);
SOFT_LINK_OPTIONAL(user32, SetProcessDpiAwarenessContext, BOOL, STDAPICALLTYPE, (DPI_AWARENESS_CONTEXT));
WKRetainPtr<WKStringRef> 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<char> 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<int>(msg.wParam);
}
extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpstrCmdLine, int nCmdShow)
{
return wWinMain(hInstance, hPrevInstance, lpstrCmdLine, nCmdShow);
}

View File

@ -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

View File

@ -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

View File

@ -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 <assert.h>
#include <comdef.h>
#include <comip.h>
#include <commctrl.h>
#include <commdlg.h>
#include <comutil.h>
#include <malloc.h>
#include <memory.h>
#include <objbase.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <stdlib.h>
#include <string>
#include <tchar.h>
#include <windows.h>
#include <wininet.h>
#include <wtf/Platform.h>
#include <JavaScriptCore/JSExportMacros.h>
#include <WebCore/PlatformExportMacros.h>
#if 0
// Visual Studio Leak Detection
// <http://msdn2.microsoft.com/en-US/library/e5ewb1h3.aspx>
#if defined(_MSC_VER) && defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B