devops: fork webkit into a separate browser (#5834)

Official WebKit no longer supports Mac 10.14. However, since
this system is still very much in use, we want to be able to
keep it running for a while.

This patch adds a new browser that we would compile and maintain
specifically for Mac 10.14: `deprecated-webkit-mac-10.14`. This
browser is a clone of Webkit r1443 that is the last known revision
to compile on Mac 10.14.

As we move on, we're free to modify this browser however we want,
backporting important patches.

References #5833
This commit is contained in:
Andrey Lushnikov 2021-03-16 01:08:21 -07:00 коммит произвёл GitHub
Родитель 5cf13612cf
Коммит e64f66685a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
51 изменённых файлов: 25488 добавлений и 5 удалений

Просмотреть файл

@ -201,11 +201,6 @@ elif [[ "$BUILD_FLAVOR" == "webkit-win64" ]]; then
BROWSER_NAME="webkit"
EXPECTED_HOST_OS="MINGW"
BUILD_BLOB_NAME="webkit-win64.zip"
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.14" ]]; then
BROWSER_NAME="webkit"
EXPECTED_HOST_OS="Darwin"
EXPECTED_HOST_OS_VERSION="10.14"
BUILD_BLOB_NAME="webkit-mac-10.14.zip"
elif [[ "$BUILD_FLAVOR" == "webkit-mac-10.15" ]]; then
BROWSER_NAME="webkit"
EXPECTED_HOST_OS="Darwin"
@ -222,6 +217,16 @@ elif [[ "$BUILD_FLAVOR" == "webkit-mac-11.0-arm64" ]]; then
EXPECTED_HOST_OS_VERSION="11.0"
EXPECTED_ARCH="arm64"
BUILD_BLOB_NAME="webkit-mac-11.0-arm64.zip"
# ===================================
# DEPRECATED WEBKIT COMPILATION
# ===================================
elif [[ "$BUILD_FLAVOR" == "deprecated-webkit-mac-10.14" ]]; then
BROWSER_NAME="deprecated-webkit-mac-10.14"
EXPECTED_HOST_OS="Darwin"
EXPECTED_HOST_OS_VERSION="10.14"
BUILD_BLOB_NAME="deprecated-webkit-mac-10.14.zip"
else
echo ERROR: unknown build flavor - "$BUILD_FLAVOR"
exit 1

1
browser_patches/deprecated-webkit-mac-10.14/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
/checkout

Просмотреть файл

@ -0,0 +1,2 @@
1443
Changed: yurys@chromium.org Mon 01 Mar 2021 09:57:46 AM PST

Просмотреть файл

@ -0,0 +1,3 @@
REMOTE_URL="https://git.webkit.org/git/WebKit.git"
BASE_BRANCH="master"
BASE_REVISION="b3de1a5d49442523744d6326dbc852cea829a145"

Просмотреть файл

@ -0,0 +1,146 @@
#!/bin/bash
set -e
set +x
if [[ ("$1" == "-h") || ("$1" == "--help") ]]; then
echo "usage: $(basename $0) [output-absolute-path]"
echo
echo "Generate distributable .zip archive from ./checkout folder that was previously built."
echo
exit 0
fi
ZIP_PATH=$1
if [[ $ZIP_PATH != /* ]]; then
echo "ERROR: path $ZIP_PATH is not absolute"
exit 1
fi
if [[ $ZIP_PATH != *.zip ]]; then
echo "ERROR: path $ZIP_PATH must have .zip extension"
exit 1
fi
if [[ -f $ZIP_PATH ]]; then
echo "ERROR: path $ZIP_PATH exists; can't do anything."
exit 1
fi
if ! [[ -d $(dirname $ZIP_PATH) ]]; then
echo "ERROR: folder for path $($ZIP_PATH) does not exist."
exit 1
fi
main() {
if [[ ! -z "${WK_CHECKOUT_PATH}" ]]; then
cd "${WK_CHECKOUT_PATH}"
echo "WARNING: checkout path from WK_CHECKOUT_PATH env: ${WK_CHECKOUT_PATH}"
else
cd "checkout"
fi
set -x
if [[ "$(uname)" == "Darwin" ]]; then
createZipForMac
elif [[ "$(uname)" == "Linux" ]]; then
createZipForLinux
elif [[ "$(uname)" == MINGW* ]]; then
createZipForWindows
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi
}
createZipForLinux() {
# create a TMP directory to copy all necessary files
local tmpdir=$(mktemp -d -t webkit-deploy-XXXXXXXXXX)
mkdir -p $tmpdir
# copy runner
cp -t $tmpdir $SCRIPTS_DIR/pw_run.sh
# copy protocol
node $SCRIPTS_DIR/concat_protocol.js > $tmpdir/protocol.json
# Generate and unpack MiniBrowser bundles for each port
for port in gtk wpe; do
WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/${port^^} Tools/Scripts/generate-bundle \
--bundle=MiniBrowser --release \
--platform=${port} --destination=${tmpdir}
unzip ${tmpdir}/MiniBrowser_${port}_release.zip -d ${tmpdir}/minibrowser-${port}
rm -f ${tmpdir}/MiniBrowser_${port}_release.zip
done
# tar resulting directory and cleanup TMP.
cd $tmpdir
zip --symlinks -r $ZIP_PATH ./
cd -
rm -rf $tmpdir
}
# see https://docs.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2019
printMSVCRedistDir() {
local dll_file=$("C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -find '**\Redist\MSVC\*\x64\**\vcruntime140.dll')
local redist_dir=$(dirname "$dll_file")
if ! [[ -d $redist_dir ]]; then
echo "ERROR: cannot find MS VS C++ redistributable $redist_dir"
exit 1;
fi
echo "$redist_dir"
}
createZipForWindows() {
# create a TMP directory to copy all necessary files
local tmpdir="/tmp/webkit-deploy-$(date +%s)"
mkdir -p $tmpdir
cp -t $tmpdir ./WebKitLibraries/win/bin64/*.dll
cd WebKitBuild/Release/bin64
cp -r -t $tmpdir WebKit.resources
cp -t $tmpdir JavaScriptCore.dll PlaywrightLib.dll WTF.dll WebKit2.dll libEGL.dll libGLESv2.dll
cp -t $tmpdir Playwright.exe WebKitNetworkProcess.exe WebKitWebProcess.exe
cd -
cd "$(printMSVCRedistDir)"
cp -t $tmpdir msvcp140.dll vcruntime140.dll vcruntime140_1.dll msvcp140_2.dll
cd -
# copy protocol
node $SCRIPTS_DIR/concat_protocol.js > $tmpdir/protocol.json
# tar resulting directory and cleanup TMP.
cd $tmpdir
zip -r $ZIP_PATH ./
cd -
rm -rf $tmpdir
}
createZipForMac() {
# create a TMP directory to copy all necessary files
local tmpdir=$(mktemp -d)
# copy all relevant files
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.Networking.xpc
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.Plugin.64.xpc
ditto {./WebKitBuild/Release,$tmpdir}/com.apple.WebKit.WebContent.xpc
ditto {./WebKitBuild/Release,$tmpdir}/JavaScriptCore.framework
ditto {./WebKitBuild/Release,$tmpdir}/libwebrtc.dylib
ditto {./WebKitBuild/Release,$tmpdir}/Playwright.app
ditto {./WebKitBuild/Release,$tmpdir}/PluginProcessShim.dylib
ditto {./WebKitBuild/Release,$tmpdir}/WebCore.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebInspectorUI.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebKit.framework
ditto {./WebKitBuild/Release,$tmpdir}/WebKitLegacy.framework
ditto {$SCRIPTS_DIR,$tmpdir}/pw_run.sh
# copy protocol
node $SCRIPTS_DIR/concat_protocol.js > $tmpdir/protocol.json
# Remove all broken symlinks. @see https://github.com/microsoft/playwright/issues/5472
find "${tmpdir}" -type l ! -exec test -e {} \; -print | xargs rm
# zip resulting directory and cleanup TMP.
ditto -c -k $tmpdir $ZIP_PATH
rm -rf $tmpdir
}
trap "cd $(pwd -P)" EXIT
cd "$(dirname "$0")"
SCRIPTS_DIR="$(pwd -P)"
main "$@"

Просмотреть файл

@ -0,0 +1,77 @@
#!/bin/bash
set -e
set +x
trap "cd $(pwd -P)" EXIT
cd "$(dirname $0)"
SCRIPT_FOLDER="$(pwd -P)"
build_gtk() {
if ! [[ -d ./WebKitBuild/GTK/DependenciesGTK ]]; then
yes | WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/GTK DEBIAN_FRONTEND=noninteractive ./Tools/Scripts/update-webkitgtk-libs
fi
local CMAKE_ARGS=""
if [[ -n "${EXPORT_COMPILE_COMMANDS}" ]]; then
CMAKE_ARGS="--cmakeargs=\"-DCMAKE_EXPORT_COMPILE_COMMANDS=1\""
fi
WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/GTK ./Tools/Scripts/build-webkit --gtk --release "${CMAKE_ARGS}" --touch-events --orientation-events --no-bubblewrap-sandbox --no-webxr MiniBrowser
}
build_wpe() {
if ! [[ -d ./WebKitBuild/WPE/DependenciesWPE ]]; then
yes | WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/WPE DEBIAN_FRONTEND=noninteractive ./Tools/Scripts/update-webkitwpe-libs
fi
local CMAKE_ARGS=""
if [[ -n "${EXPORT_COMPILE_COMMANDS}" ]]; then
CMAKE_ARGS="--cmakeargs=\"-DCMAKE_EXPORT_COMPILE_COMMANDS=1\""
fi
WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/WPE ./Tools/Scripts/build-webkit --wpe --release "${CMAKE_ARGS}" --touch-events --orientation-events --no-bubblewrap-sandbox --no-webxr MiniBrowser
}
ensure_linux_deps() {
yes | DEBIAN_FRONTEND=noninteractive ./Tools/gtk/install-dependencies
yes | DEBIAN_FRONTEND=noninteractive ./Tools/wpe/install-dependencies
yes | DEBIAN_FRONTEND=noninteractive WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/WPE ./Tools/Scripts/update-webkitwpe-libs
yes | DEBIAN_FRONTEND=noninteractive WEBKIT_JHBUILD=1 WEBKIT_JHBUILD_MODULESET=minimal WEBKIT_OUTPUTDIR=$(pwd)/WebKitBuild/GTK ./Tools/Scripts/update-webkitgtk-libs
}
if [[ ! -z "${WK_CHECKOUT_PATH}" ]]; then
cd "${WK_CHECKOUT_PATH}"
echo "WARNING: checkout path from WK_CHECKOUT_PATH env: ${WK_CHECKOUT_PATH}"
else
cd "checkout"
fi
if [[ "$(uname)" == "Darwin" ]]; then
./Tools/Scripts/build-webkit --release --touch-events --orientation-events
elif [[ "$(uname)" == "Linux" ]]; then
if [[ $# == 0 || (-z "$1") ]]; then
echo
echo BUILDING: GTK and WPE
echo
build_wpe
build_gtk
elif [[ "$1" == "--full" ]]; then
echo
echo BUILDING: GTK and WPE
echo
ensure_linux_deps
build_wpe
build_gtk
elif [[ "$1" == "--gtk" ]]; then
echo
echo BUILDING: GTK
echo
build_gtk
elif [[ "$1" == "--wpe" ]]; then
echo
echo BUILDING: WPE
echo
build_wpe
fi
elif [[ "$(uname)" == MINGW* ]]; then
/c/Windows/System32/cmd.exe "/c $(cygpath -w ${SCRIPT_FOLDER}/buildwin.bat)"
else
echo "ERROR: cannot upload on this platform!" 1>&2
exit 1;
fi

Просмотреть файл

@ -0,0 +1,5 @@
set PATH=%WEBKIT_BUILD_PATH%
set WEBKIT_LIBRARIES=%CD%\WebKitLibraries\win
set WEBKIT_OUTPUTDIR=%CD%\WebKitBuild
perl %CD%\Tools\Scripts\build-webkit --wincairo --release --no-ninja --touch-events --orientation-events --dark-mode-css --generate-project-only --cmakeargs="-DLIBVPX_PACKAGE_PATH=C:\vcpkg\packages\libvpx_x64-windows"
%DEVENV% %CD%\WebKitBuild\Release\WebKit.sln /build "Release|x64"

Просмотреть файл

@ -0,0 +1,23 @@
#!/bin/bash
set -e
set +x
trap "cd $(pwd -P)" EXIT
cd "$(dirname $0)"
if [[ ! -z "${WK_CHECKOUT_PATH}" ]]; then
cd "${WK_CHECKOUT_PATH}"
echo "WARNING: checkout path from WK_CHECKOUT_PATH env: ${WK_CHECKOUT_PATH}"
else
cd "checkout"
fi
if [[ -d ./WebKitBuild ]]; then
rm -rf ./WebKitBuild/Release
fi
if [[ -d ./WebKitBuild/GTK ]]; then
rm -rf ./WebKitBuild/GTK/Release
fi
if [[ -d ./WebKitBuild/WPE ]]; then
rm -rf ./WebKitBuild/WPE/Release
fi

Просмотреть файл

@ -0,0 +1,7 @@
const fs = require('fs');
const path = require('path');
const checkoutPath = process.env.WK_CHECKOUT_PATH || path.join(__dirname, 'checkout');
const protocolDir = path.join(checkoutPath, './Source/JavaScriptCore/inspector/protocol');
const files = fs.readdirSync(protocolDir).filter(f => f.endsWith('.json')).map(f => path.join(protocolDir, f));
const json = files.map(file => JSON.parse(fs.readFileSync(file)));
console.log(JSON.stringify(json));

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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 */;
}

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,53 @@
/*
* 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;
NSString* _proxyServer;
NSString* _proxyBypassList;
IBOutlet NSMenuItem *_newWebKit2WindowItem;
}
@end
@interface NSApplication (PlaywrightApplicationExtensions)
- (BrowserAppDelegate *)browserAppDelegate;
@end

Просмотреть файл

@ -0,0 +1,494 @@
/*
* 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;
_proxyServer = nil;
_proxyBypassList = 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];
}
if ([argument hasPrefix:@"--proxy="]) {
NSRange range = NSMakeRange(8, [argument length] - 8);
_proxyServer = [[argument substringWithRange:range] copy];
}
if ([argument hasPrefix:@"--proxy-bypass-list="]) {
NSRange range = NSMakeRange(20, [argument length] - 20);
_proxyBypassList = [[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];
}
- (NSDictionary *)proxyConfiguration:(NSString *)proxyServer WithBypassList:(NSString *)proxyBypassList
{
if (!proxyServer || ![proxyServer length])
return nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc] init] autorelease];
NSURL *proxyURL = [NSURL URLWithString:proxyServer];
NSString *host = [proxyURL host];
NSNumber *port = [proxyURL port];
if ([proxyServer hasPrefix:@"socks5://"]) {
[dictionary setObject:host forKey:(NSString *)kCFStreamPropertySOCKSProxyHost];
if (port)
[dictionary setObject:port forKey:(NSString *)kCFStreamPropertySOCKSProxyPort];
} else {
[dictionary setObject:host forKey:(NSString *)kCFStreamPropertyHTTPSProxyHost];
[dictionary setObject:host forKey:(NSString *)kCFStreamPropertyHTTPProxyHost];
if (port) {
[dictionary setObject:port forKey:(NSString *)kCFStreamPropertyHTTPSProxyPort];
[dictionary setObject:port forKey:(NSString *)kCFStreamPropertyHTTPProxyPort];
}
}
if (proxyBypassList && [proxyBypassList length]) {
NSArray* bypassList = [proxyBypassList componentsSeparatedByString:@","];
[dictionary setObject:bypassList forKey:@"ExceptionsList"];
}
#pragma clang diagnostic pop
return dictionary;
}
- (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];
}
[configuration setProxyConfiguration:[self proxyConfiguration:_proxyServer WithBypassList:_proxyBypassList]];
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] autorelease];
}
return configuration;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
if (!_headless)
[self _updateNewWindowKeyEquivalents];
if (_noStartupWindow)
return;
// Force creation of the default browser context.
[self defaultConfiguration];
// Creating the first NSWindow immediately makes it invisible in headless mode,
// so we postpone it for 50ms. Experiments show that 10ms is not enough, and 20ms is enough.
// We give it 50ms just in case.
[NSTimer scheduledTimerWithTimeInterval: 0.05
repeats: NO
block:(void *)^(NSTimer* timer)
{
[self createNewPage:0 withURL:_initialURL ? _initialURL : @"about:blank"];
_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
{
return [self createNewPage:sessionID withURL:@"about:blank"];
}
- (WKWebView *)createNewPage:(uint64_t)sessionID withURL:(NSString*)urlString
{
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];
NSWindow *window = controller.window;
[window setIsVisible:YES];
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];
[window setIsVisible:YES];
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:(NSString *)proxyServer WithBypassList:(NSString *) proxyBypassList
{
_WKBrowserContext *browserContext = [[_WKBrowserContext alloc] init];
_WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
processConfiguration.forceOverlayScrollbars = YES;
_WKWebsiteDataStoreConfiguration *dataStoreConfiguration = [[[_WKWebsiteDataStoreConfiguration alloc] initNonPersistentConfiguration] autorelease];
if (!proxyServer || ![proxyServer length])
proxyServer = _proxyServer;
if (!proxyBypassList || ![proxyBypassList length])
proxyBypassList = _proxyBypassList;
[dataStoreConfiguration setProxyConfiguration:[self proxyConfiguration:proxyServer WithBypassList:proxyBypassList]];
browserContext.dataStore = [[[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration] autorelease];
browserContext.processPool = [[[WKProcessPool alloc] _initWithConfiguration:processConfiguration] autorelease];
[_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 {
[self webView:webView handleJavaScriptDialog:false value:nil];
for (NSWindow *window in _headlessWindows) {
if (webView.window != window)
continue;
[webView removeFromSuperview];
[window close];
[_headlessWindows removeObject:window];
break;
}
}
- (void)_webView:(WKWebView *)webView getWindowFrameWithCompletionHandler:(void (^)(CGRect))completionHandler
{
completionHandler([webView.window frame]);
}
- (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.shouldPerformDownload) {
decisionHandler(WKNavigationActionPolicyDownload);
return;
}
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(WKNavigationResponsePolicyDownload);
return;
}
decisionHandler(WKNavigationResponsePolicyAllow);
}
- (void)webView:(WKWebView *)webView navigationAction:(WKNavigationAction *)navigationAction didBecomeDownload:(WKDownload *)download
{
download.delegate = self;
}
- (void)webView:(WKWebView *)webView navigationResponse:(WKNavigationResponse *)navigationResponse didBecomeDownload:(WKDownload *)download
{
download.delegate = self;
}
#pragma mark WKDownloadDelegate
- (void)download:(WKDownload *)download decideDestinationUsingResponse:(NSURLResponse *)response suggestedFilename:(NSString *)suggestedFilename completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
{
completionHandler(nil);
}
@end

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,877 @@
/*
* 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];
// Post two events (don't ask me why!) to spin event loop and drain
// automatically created autorelease pools that will release our window.
// See https://www.mikeash.com/pyblog/more-fun-with-autorelease.html
// for some discussion.
NSEvent* event1 = [NSEvent
otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:[[NSDate date] timeIntervalSince1970]
windowNumber:0
context:nil
subtype:0
data1:0
data2:0];
[NSApp postEvent:event1 atStart:YES];
NSEvent* event2 = [NSEvent
otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:[[NSDate date] timeIntervalSince1970]
windowNumber:0
context:nil
subtype:0
data1:0
data2:0];
[NSApp postEvent:event2 atStart:NO];
}
- (void)webViewDidClose:(WKWebView *)webView {
[self webView:webView handleJavaScriptDialog:false value:nil];
[self.window close];
}
- (void)_webView:(WKWebView *)webView getWindowFrameWithCompletionHandler:(void (^)(CGRect))completionHandler
{
completionHandler([self.window frame]);
}
#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 = title;
}
- (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.shouldPerformDownload) {
decisionHandler(WKNavigationActionPolicyDownload);
return;
}
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(WKNavigationResponsePolicyDownload);
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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,41 @@
set(Playwright_PRIVATE_INCLUDE_DIRECTORIES
${CMAKE_BINARY_DIR}
${WebCore_PRIVATE_FRAMEWORK_HEADERS_DIR}
)
set(Playwright_SOURCES
Common.cpp
MainWindow.cpp
PlaywrightLib.rc
WebKitBrowserWindow.cpp
WinMain.cpp
stdafx.cpp
)
set(Playwright_PRIVATE_DEFINITIONS _UNICODE)
set(Playwright_PRIVATE_LIBRARIES
WebKit::WTF
comctl32
shlwapi
user32
)
list(APPEND Playwright_PRIVATE_DEFINITIONS ENABLE_WEBKIT)
list(APPEND Playwright_SOURCES
WebKitBrowserWindow.cpp
)
list(APPEND Playwright_PRIVATE_LIBRARIES
WebKit::WebKit
)
WEBKIT_EXECUTABLE_DECLARE(Playwright)
WEBKIT_WRAP_EXECUTABLE(Playwright
SOURCES ${TOOLS_DIR}/win/DLLLauncher/DLLLauncherMain.cpp Playwright.rc
LIBRARIES shlwapi
)
WEBKIT_EXECUTABLE(Playwright)
set_target_properties(Playwright PROPERTIES WIN32_EXECUTABLE ON)
if (${WTF_PLATFORM_WIN_CAIRO})
target_compile_definitions(Playwright PRIVATE WIN_CAIRO)
endif ()

Просмотреть файл

@ -0,0 +1,269 @@
/*
* 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());
}
}
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 (!wcsncmp(argv[i], L"--curl-proxy=", 13))
options.curloptProxy = argv[i] + 13;
else if (!wcsncmp(argv[i], L"--curl-noproxy=", 15))
options.curloptNoproxy = argv[i] + 15;
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()));
}

Просмотреть файл

@ -0,0 +1,73 @@
/*
* 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;
_bstr_t curloptProxy;
_bstr_t curloptNoproxy;
CommandLineOptions()
{
}
};
struct Credential {
std::wstring username;
std::wstring password;
};
void computeFullDesktopFrame();
bool getAppDataFolder(_bstr_t& directory);
CommandLineOptions parseCommandLine();
void createCrashReport(EXCEPTION_POINTERS*);
Optional<Credential> askCredential(HWND, const std::wstring& realm);
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);

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,459 @@
/*
* 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, WKPageConfigurationRef conf)
{
auto prefs = adoptWK(WKPreferencesCreate());
WKPageConfigurationSetPreferences(conf, prefs.get());
WKPreferencesSetMediaCapabilitiesEnabled(prefs.get(), false);
WKPreferencesSetDeveloperExtrasEnabled(prefs.get(), true);
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_NCDESTROY:
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());
}

Просмотреть файл

@ -0,0 +1,83 @@
/*
* 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, 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 { };
};

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 120 KiB

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,393 @@
/*
* 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;
uiClient.getWindowFrame = getWindowFrame;
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;
}
}
WKRect WebKitBrowserWindow::getWindowFrame(WKPageRef page, const void *clientInfo) {
auto& thisWindow = toWebKitBrowserWindow(clientInfo);
WKRect wkFrame { };
RECT r;
if (::GetWindowRect(thisWindow.m_hMainWnd, &r)) {
wkFrame.origin.x = r.left;
wkFrame.origin.y = r.top;
wkFrame.size.width = r.right - r.left;
wkFrame.size.height = r.bottom - r.top;
}
return wkFrame;
}
WKPageRef WebKitBrowserWindow::createPageCallback(WKPageConfigurationRef configuration)
{
// This comes from the Playwright agent, configuration is a pool+data pair.
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*)
{
// This comes from the client for popups, configuration is inherited from main page.
// 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);
}

Просмотреть файл

@ -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 WKRect getWindowFrame(WKPageRef page, 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 };
std::unordered_map<std::wstring, std::wstring> m_acceptedServerTrustCerts;
WKPageRunJavaScriptAlertResultListenerRef m_alertDialog = { };
WKPageRunJavaScriptConfirmResultListenerRef m_confirmDialog = { };
WKPageRunJavaScriptPromptResultListenerRef m_promptDialog = { };
WKPageRunBeforeUnloadConfirmPanelResultListenerRef m_beforeUnloadDialog = { };
};

Просмотреть файл

@ -0,0 +1,172 @@
/*
* 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 <WebKit/WKWebsiteDataStoreRefCurl.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));
CommandLineOptions g_options;
static WKRetainPtr<WKStringRef> toWK(const std::string& string)
{
return adoptWK(WKStringCreateWithUTF8CString(string.c_str()));
}
static 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 };
}
static void configureDataStore(WKWebsiteDataStoreRef dataStore) {
if (g_options.curloptProxy.length()) {
auto curloptProxy = createWKURL(g_options.curloptProxy);
auto curloptNoproxy = createWKString(g_options.curloptNoproxy);
WKWebsiteDataStoreEnableCustomNetworkProxySettings(dataStore, curloptProxy.get(), curloptNoproxy.get());
}
}
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);
g_options = parseCommandLine();
if (g_options.inspectorPipe) {
WKInspectorInitializeRemoteInspectorPipe(
configureDataStore,
WebKitBrowserWindow::createPageCallback,
[]() { PostQuitMessage(0); });
}
if (g_options.useFullDesktop)
computeFullDesktopFrame();
// Init COM
OleInitialize(nullptr);
if (SetProcessDpiAwarenessContextPtr())
SetProcessDpiAwarenessContextPtr()(DPI_AWARENESS_CONTEXT_UNAWARE);
MainWindow::configure(g_options.headless, g_options.noStartupWindow);
if (!g_options.noStartupWindow) {
auto configuration = adoptWK(WKWebsiteDataStoreConfigurationCreate());
if (g_options.userDataDir.length()) {
std::string profileFolder = toUTF8String(g_options.userDataDir, g_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()));
configureDataStore(dataStore.get());
auto* mainWindow = new MainWindow();
auto conf = adoptWK(WKPageConfigurationCreate());
WKPageConfigurationSetContext(conf.get(), context.get());
WKPageConfigurationSetWebsiteDataStore(conf.get(), dataStore.get());
HRESULT hr = mainWindow->init(hInst, conf.get());
if (FAILED(hr))
goto exit;
if (g_options.requestedURL.length())
mainWindow->loadURL(g_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);
}

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 982 B

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,77 @@
#!/bin/bash
function runOSX() {
# if script is run as-is
if [[ -d $SCRIPT_PATH/checkout/WebKitBuild/Release/Playwright.app ]]; then
DYLIB_PATH="$SCRIPT_PATH/checkout/WebKitBuild/Release"
elif [[ -d $SCRIPT_PATH/Playwright.app ]]; then
DYLIB_PATH="$SCRIPT_PATH"
elif [[ -d $SCRIPT_PATH/WebKitBuild/Release/Playwright.app ]]; then
DYLIB_PATH="$SCRIPT_PATH/WebKitBuild/Release"
else
echo "Cannot find a Playwright.app in neither location" 1>&2
exit 1
fi
PLAYWRIGHT="$DYLIB_PATH/Playwright.app/Contents/MacOS/Playwright"
DYLD_FRAMEWORK_PATH="$DYLIB_PATH" DYLD_LIBRARY_PATH="$DYLIB_PATH" "$PLAYWRIGHT" "$@"
}
function runLinux() {
# if script is run as-is
GIO_DIR="";
LD_PATH="";
BUNDLE_DIR="";
DEPENDENCIES_FOLDER="DependenciesGTK";
MINIBROWSER_FOLDER="minibrowser-gtk";
BUILD_FOLDER="WebKitBuild/GTK";
if [[ "$*" == *--headless* ]]; then
DEPENDENCIES_FOLDER="DependenciesWPE";
MINIBROWSER_FOLDER="minibrowser-wpe";
BUILD_FOLDER="WebKitBuild/WPE";
fi
# Setting extra environment variables like LD_LIBRARY_PATH or WEBKIT_INJECTED_BUNDLE_PATH
# is only needed when calling MiniBrowser from the build folder. The MiniBrowser from
# the zip bundle wrapper already sets itself the needed env variables.
if [[ -d $SCRIPT_PATH/$MINIBROWSER_FOLDER ]]; then
MINIBROWSER="$SCRIPT_PATH/$MINIBROWSER_FOLDER/MiniBrowser"
elif [[ -d $SCRIPT_PATH/checkout/$BUILD_FOLDER ]]; then
LD_PATH="$SCRIPT_PATH/checkout/$BUILD_FOLDER/$DEPENDENCIES_FOLDER/Root/lib:$SCRIPT_PATH/checkout/$BUILD_FOLDER/Release/bin"
GIO_DIR="$SCRIPT_PATH/checkout/$BUILD_FOLDER/$DEPENDENCIES_FOLDER/Root/lib/gio/modules"
BUNDLE_DIR="$SCRIPT_PATH/checkout/$BUILD_FOLDER/Release/lib"
MINIBROWSER="$SCRIPT_PATH/checkout/$BUILD_FOLDER/Release/bin/MiniBrowser"
elif [[ -f $SCRIPT_PATH/MiniBrowser ]]; then
MINIBROWSER="$SCRIPT_PATH/MiniBrowser"
elif [[ -d $SCRIPT_PATH/$BUILD_FOLDER ]]; then
LD_PATH="$SCRIPT_PATH/$BUILD_FOLDER/$DEPENDENCIES_FOLDER/Root/lib:$SCRIPT_PATH/$BUILD_FOLDER/Release/bin"
GIO_DIR="$SCRIPT_PATH/$BUILD_FOLDER/$DEPENDENCIES_FOLDER/Root/lib/gio/modules"
BUNDLE_DIR="$SCRIPT_PATH/$BUILD_FOLDER/Release/lib"
MINIBROWSER="$SCRIPT_PATH/$BUILD_FOLDER/Release/bin/MiniBrowser"
else
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
exit 1
fi
if [[ -n "$GIO_DIR" ]]; then
export GIO_EXTRA_MODULES="$GIO_DIR"
fi
if [[ -n "$LD_PATH" ]]; then
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LD_PATH"
fi
if [[ -n "$BUNDLE_DIR" ]]; then
export WEBKIT_INJECTED_BUNDLE_PATH="$BUNDLE_DIR"
fi
WEBKIT_FORCE_COMPLEX_TEXT="1" "$MINIBROWSER" "$@"
}
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
if [[ "$(uname)" == "Darwin" ]]; then
runOSX "$@"
elif [[ "$(uname)" == "Linux" ]]; then
runLinux "$@"
else
echo "ERROR: cannot run on this platform!" 1>&2
exit 1;
fi

Просмотреть файл

@ -0,0 +1,45 @@
#!/bin/bash
function runOSX() {
# if script is run as-is
if [ -d $SCRIPT_PATH/checkout/WebKitBuild/Debug/MiniBrowser.app ]; then
DYLIB_PATH="$SCRIPT_PATH/checkout/WebKitBuild/Debug"
elif [ -d $SCRIPT_PATH/MiniBrowser.app ]; then
DYLIB_PATH="$SCRIPT_PATH"
elif [ -d $SCRIPT_PATH/WebKitBuild/Debug/MiniBrowser.app ]; then
DYLIB_PATH="$SCRIPT_PATH/WebKitBuild/Debug"
else
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
exit 1
fi
MINIBROWSER="$DYLIB_PATH/MiniBrowser.app/Contents/MacOS/MiniBrowser"
DYLD_FRAMEWORK_PATH=$DYLIB_PATH DYLD_LIBRARY_PATH=$DYLIB_PATH $MINIBROWSER "$@"
}
function runLinux() {
# if script is run as-is
if [ -d $SCRIPT_PATH/checkout/WebKitBuild/GTK ]; then
LD_PATH="$SCRIPT_PATH/checkout/WebKitBuild/GTK/DependenciesGTK/Root/lib:$SCRIPT_PATH/checkout/WebKitBuild/GTK/Debug/bin"
MINIBROWSER="$SCRIPT_PATH/checkout/WebKitBuild/GTK/Debug/bin/MiniBrowser"
elif [ -f $SCRIPT_PATH/MiniBrowser ]; then
LD_PATH="$SCRIPT_PATH"
MINIBROWSER="$SCRIPT_PATH/MiniBrowser"
elif [ -d $SCRIPT_PATH/WebKitBuild/GTK ]; then
LD_PATH="$SCRIPT_PATH/WebKitBuild/GTK/DependenciesGTK/Root/lib:$SCRIPT_PATH/WebKitBuild/GTK/Debug/bin"
MINIBROWSER="$SCRIPT_PATH/WebKitBuild/GTK/Debug/bin/MiniBrowser"
else
echo "Cannot find a MiniBrowser.app in neither location" 1>&2
exit 1
fi
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_PATH $MINIBROWSER "$@"
}
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"
if [ "$(uname)" == "Darwin" ]; then
runOSX "$@"
elif [ "$(uname)" == "Linux" ]; then
runLinux "$@"
else
echo "ERROR: cannot run on this platform!" 1>&2
exit 1;
fi

Просмотреть файл

@ -93,6 +93,18 @@ elif [[ ("$1" == "firefox") || ("$1" == "firefox/") || ("$1" == "ff") ]]; then
CHECKOUT_PATH="${FF_CHECKOUT_PATH}"
FRIENDLY_CHECKOUT_PATH="<FF_CHECKOUT_PATH>"
fi
elif [[ ("$1" == "deprecated-webkit-mac-10.14") ]]; then
FRIENDLY_CHECKOUT_PATH="//browser_patches/deprecated-webkit-mac-10.14/checkout";
CHECKOUT_PATH="$PWD/deprecated-webkit-mac-10.14/checkout"
PATCHES_PATH="$PWD/deprecated-webkit-mac-10.14/patches"
WEBKIT_EXTRA_FOLDER_PATH="$PWD/deprecated-webkit-mac-10.14/embedder/Playwright"
BUILD_NUMBER=$(head -1 "$PWD/deprecated-webkit-mac-10.14/BUILD_NUMBER")
source "./deprecated-webkit-mac-10.14/UPSTREAM_CONFIG.sh"
if [[ ! -z "${WK_CHECKOUT_PATH}" ]]; then
echo "WARNING: using checkout path from WK_CHECKOUT_PATH env: ${WK_CHECKOUT_PATH}"
CHECKOUT_PATH="${WK_CHECKOUT_PATH}"
FRIENDLY_CHECKOUT_PATH="<WK_CHECKOUT_PATH>"
fi
elif [[ ("$1" == "webkit") || ("$1" == "webkit/") || ("$1" == "wk") ]]; then
FRIENDLY_CHECKOUT_PATH="//browser_patches/webkit/checkout";
CHECKOUT_PATH="$PWD/webkit/checkout"