blob: 48167d7aac1216e80f4af830371201cff2a6693c [file] [log] [blame]
/*
* 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 "WebKitBrowserWindow.h"
#include "MiniBrowserLibResource.h"
#include "common.h"
#include <WebKit/WKAuthenticationChallenge.h>
#include <WebKit/WKAuthenticationDecisionListener.h>
#include <WebKit/WKCredential.h>
#include <WebKit/WKInspector.h>
#include <WebKit/WKProtectionSpace.h>
#include <vector>
std::wstring createString(WKStringRef wkString)
{
size_t maxSize = WKStringGetLength(wkString);
std::wstring str(maxSize, '\0');
size_t actualLength = WKStringGetCharacters(wkString, str.data(), maxSize);
if (maxSize != actualLength)
str.resize(actualLength);
return std::wstring(str.data());
}
std::wstring createString(WKURLRef wkURL)
{
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::string str(length, '\0');
int actualLength = WideCharToMultiByte(CP_UTF8, 0, src, srcLength, str.data(), length, nullptr, nullptr);
if (length != actualLength)
str.resize(actualLength);
return str;
}
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()));
}
Ref<BrowserWindow> WebKitBrowserWindow::create(HWND mainWnd, HWND urlBarWnd, bool, bool)
{
return adoptRef(*new WebKitBrowserWindow(mainWnd, urlBarWnd));
}
WebKitBrowserWindow::WebKitBrowserWindow(HWND mainWnd, HWND urlBarWnd)
: m_hMainWnd(mainWnd)
, m_urlBarWnd(urlBarWnd)
{
RECT rect = { };
auto conf = adoptWK(WKPageConfigurationCreate());
auto prefs = WKPreferencesCreate();
WKPreferencesSetDeveloperExtrasEnabled(prefs, true);
WKPageConfigurationSetPreferences(conf.get(), prefs);
auto context = adoptWK(WKContextCreate());
WKPageConfigurationSetContext(conf.get(), context.get());
m_view = adoptWK(WKViewCreate(rect, conf.get(), mainWnd));
auto page = WKViewGetPage(m_view.get());
WKPageNavigationClientV0 navigationClient = {{ 0, this }};
navigationClient.didFinishNavigation = didFinishNavigation;
navigationClient.didCommitNavigation = didCommitNavigation;
navigationClient.didReceiveAuthenticationChallenge = didReceiveAuthenticationChallenge;
WKPageSetPageNavigationClient(page, &navigationClient.base);
}
HRESULT WebKitBrowserWindow::init()
{
return S_OK;
}
HWND WebKitBrowserWindow::hwnd()
{
return WKViewGetWindow(m_view.get());
}
HRESULT WebKitBrowserWindow::loadURL(const BSTR& url)
{
auto page = WKViewGetPage(m_view.get());
WKPageLoadURL(page, createWKURL(url).get());
return true;
}
HRESULT WebKitBrowserWindow::loadHTMLString(const BSTR& str)
{
auto page = WKViewGetPage(m_view.get());
auto url = createWKURL(L"about:");
WKPageLoadHTMLString(page, createWKString(_bstr_t(str)).get(), url.get());
return true;
}
void WebKitBrowserWindow::navigateForwardOrBackward(UINT menuID)
{
auto page = WKViewGetPage(m_view.get());
if (menuID == IDM_HISTORY_FORWARD)
WKPageGoForward(page);
else
WKPageGoBack(page);
}
void WebKitBrowserWindow::navigateToHistory(UINT menuID)
{
// Not implemented
}
void WebKitBrowserWindow::setPreference(UINT menuID, bool enable)
{
auto page = WKViewGetPage(m_view.get());
auto pgroup = WKPageGetPageGroup(page);
auto pref = WKPageGroupGetPreferences(pgroup);
switch (menuID) {
case IDM_DISABLE_IMAGES:
WKPreferencesSetLoadsImagesAutomatically(pref, !enable);
break;
case IDM_DISABLE_JAVASCRIPT:
WKPreferencesSetJavaScriptEnabled(pref, !enable);
break;
}
}
void WebKitBrowserWindow::print()
{
// Not implemented
}
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::showLayerTree()
{
// Not implemented
}
void WebKitBrowserWindow::updateStatistics(HWND hDlg)
{
// Not implemented
}
void WebKitBrowserWindow::resetZoom()
{
auto page = WKViewGetPage(m_view.get());
WKPageSetPageZoomFactor(page, 1);
}
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::didFinishNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo)
{
WKRetainPtr<WKStringRef> title = adoptWK(WKPageCopyTitle(page));
std::wstring titleString = createString(title.get()) + L" [WebKit]";
auto& thisWindow = toWebKitBrowserWindow(clientInfo);
SetWindowText(thisWindow.m_hMainWnd, titleString.c_str());
}
void WebKitBrowserWindow::didCommitNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo)
{
auto& thisWindow = toWebKitBrowserWindow(clientInfo);
WKRetainPtr<WKURLRef> wkurl = adoptWK(WKPageCopyCommittedURL(page));
std::wstring urlString = createString(wkurl.get());
SetWindowText(thisWindow.m_urlBarWnd, urlString.c_str());
}
void WebKitBrowserWindow::didReceiveAuthenticationChallenge(WKPageRef page, WKAuthenticationChallengeRef challenge, const void* clientInfo)
{
auto& thisWindow = toWebKitBrowserWindow(clientInfo);
auto protectionSpace = WKAuthenticationChallengeGetProtectionSpace(challenge);
auto decisionListener = WKAuthenticationChallengeGetDecisionListener(challenge);
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;
}
WKAuthenticationDecisionListenerCancel(decisionListener);
}