blob: 3de9fe55c126cc35c2bf6a3276458b775624bcef [file] [log] [blame]
/*
* 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 "WebKitLegacyBrowserWindow.h"
#include "AccessibilityDelegate.h"
#include "Common.h"
#include "DOMDefaultImpl.h"
#include "MiniBrowserLibResource.h"
#include "MiniBrowserReplace.h"
#include "MiniBrowserWebHost.h"
#include "PrintWebUIDelegate.h"
#include "ResourceLoadDelegate.h"
#include "WebDownloadDelegate.h"
#include <WebCore/COMPtr.h>
#include <WebKitLegacy/WebKitCOMAPI.h>
#include <algorithm>
#include <cassert>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <wtf/text/WTFString.h>
#if USE(CF)
#include <WebKitLegacy/CFDictionaryPropertyBag.h>
#endif
namespace WebCore {
float deviceScaleFactorForWindow(HWND);
}
static const int maxHistorySize = 10;
typedef _com_ptr_t<_com_IIID<IWebMutableURLRequest, &__uuidof(IWebMutableURLRequest)>> IWebMutableURLRequestPtr;
Ref<BrowserWindow> WebKitLegacyBrowserWindow::create(HWND mainWnd, HWND urlBarWnd, bool useLayeredWebView, bool pageLoadTesting)
{
return adoptRef(*new WebKitLegacyBrowserWindow(mainWnd, urlBarWnd, useLayeredWebView, pageLoadTesting));
}
WebKitLegacyBrowserWindow::WebKitLegacyBrowserWindow(HWND mainWnd, HWND urlBarWnd, bool useLayeredWebView, bool pageLoadTesting)
: m_hMainWnd(mainWnd)
, m_hURLBarWnd(urlBarWnd)
, m_useLayeredWebView(useLayeredWebView)
, m_pageLoadTestClient(std::make_unique<PageLoadTestClient>(this, pageLoadTesting))
{
}
ULONG WebKitLegacyBrowserWindow::AddRef()
{
ref();
return refCount();
}
ULONG WebKitLegacyBrowserWindow::Release()
{
auto count = refCount();
deref();
return --count;
}
HRESULT WebKitLegacyBrowserWindow::init()
{
HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, reinterpret_cast<void**>(&m_webView.GetInterfacePtr()));
if (FAILED(hr))
return hr;
hr = m_webView->QueryInterface(IID_IWebViewPrivate2, reinterpret_cast<void**>(&m_webViewPrivate.GetInterfacePtr()));
if (FAILED(hr))
return hr;
hr = WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(m_webHistory), reinterpret_cast<void**>(&m_webHistory.GetInterfacePtr()));
if (FAILED(hr))
return hr;
hr = WebKitCreateInstance(CLSID_WebCoreStatistics, 0, __uuidof(m_statistics), reinterpret_cast<void**>(&m_statistics.GetInterfacePtr()));
if (FAILED(hr))
return hr;
hr = WebKitCreateInstance(CLSID_WebCache, 0, __uuidof(m_webCache), reinterpret_cast<void**>(&m_webCache.GetInterfacePtr()));
if (FAILED(hr))
return hr;
if (!seedInitialDefaultPreferences())
return E_FAIL;
if (!setToDefaultPreferences())
return E_FAIL;
if (!setCacheFolder())
return E_FAIL;
auto webHost = new MiniBrowserWebHost(this, m_hURLBarWnd);
hr = setFrameLoadDelegate(webHost);
if (FAILED(hr))
return hr;
hr = setFrameLoadDelegatePrivate(webHost);
if (FAILED(hr))
return hr;
hr = setUIDelegate(new PrintWebUIDelegate(*this));
if (FAILED (hr))
return hr;
hr = setAccessibilityDelegate(new AccessibilityDelegate(*this));
if (FAILED (hr))
return hr;
hr = setResourceLoadDelegate(new ResourceLoadDelegate(this));
if (FAILED(hr))
return hr;
IWebDownloadDelegatePtr downloadDelegate;
downloadDelegate.Attach(new WebDownloadDelegate(*this));
hr = setDownloadDelegate(downloadDelegate);
if (FAILED(hr))
return hr;
RECT clientRect;
::GetClientRect(m_hMainWnd, &clientRect);
if (usesLayeredWebView())
clientRect = { s_windowPosition.x, s_windowPosition.y, s_windowPosition.x + s_windowSize.cx, s_windowPosition.y + s_windowSize.cy };
hr = prepareViews(m_hMainWnd, clientRect);
if (FAILED(hr))
return hr;
if (usesLayeredWebView())
subclassForLayeredWindow();
return hr;
}
bool WebKitLegacyBrowserWindow::setCacheFolder()
{
_bstr_t appDataFolder;
if (!getAppDataFolder(appDataFolder))
return false;
appDataFolder += L"\\cache";
webCache()->setCacheFolder(appDataFolder);
return true;
}
HRESULT WebKitLegacyBrowserWindow::prepareViews(HWND mainWnd, const RECT& clientRect)
{
if (!m_webView)
return E_FAIL;
HRESULT hr = m_webView->setHostWindow(mainWnd);
if (FAILED(hr))
return hr;
hr = m_webView->initWithFrame(clientRect, 0, 0);
if (FAILED(hr))
return hr;
hr = m_webViewPrivate->setTransparent(m_useLayeredWebView);
if (FAILED(hr))
return hr;
hr = m_webViewPrivate->setUsesLayeredWindow(m_useLayeredWebView);
if (FAILED(hr))
return hr;
hr = m_webViewPrivate->viewWindow(&m_viewWnd);
return hr;
}
HRESULT WebKitLegacyBrowserWindow::loadHTMLString(const BSTR& str)
{
IWebFramePtr frame;
HRESULT hr = m_webView->mainFrame(&frame.GetInterfacePtr());
if (FAILED(hr))
return hr;
frame->loadHTMLString(str, 0);
return hr;
}
static WNDPROC gDefWebKitProc;
static LRESULT CALLBACK viewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_NCHITTEST:
constexpr int dragBarHeight = 30;
RECT window;
::GetWindowRect(hWnd, &window);
// For testing our transparent window, we need a region to use as a handle for
// dragging. The right way to do this would be to query the web view to see what's
// under the mouse. However, for testing purposes we just use an arbitrary
// 30 logical pixel band at the top of the view as an arbitrary gripping location.
//
// When we are within this bad, return HT_CAPTION to tell Windows we want to
// treat this region as if it were the title bar on a normal window.
int y = HIWORD(lParam);
float scaledDragBarHeightFactor = dragBarHeight * WebCore::deviceScaleFactorForWindow(hWnd);
if ((y > window.top) && (y < window.top + scaledDragBarHeightFactor))
return HTCAPTION;
}
return CallWindowProc(gDefWebKitProc, hWnd, message, wParam, lParam);
}
void WebKitLegacyBrowserWindow::subclassForLayeredWindow()
{
#if defined _M_AMD64 || defined _WIN64
gDefWebKitProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtr(m_viewWnd, GWLP_WNDPROC));
::SetWindowLongPtr(m_viewWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(viewWndProc));
#else
gDefWebKitProc = reinterpret_cast<WNDPROC>(::GetWindowLong(m_viewWnd, GWL_WNDPROC));
::SetWindowLong(m_viewWnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(viewWndProc));
#endif
}
HRESULT WebKitLegacyBrowserWindow::setFrameLoadDelegate(IWebFrameLoadDelegate* frameLoadDelegate)
{
m_frameLoadDelegate = frameLoadDelegate;
return m_webView->setFrameLoadDelegate(frameLoadDelegate);
}
HRESULT WebKitLegacyBrowserWindow::setFrameLoadDelegatePrivate(IWebFrameLoadDelegatePrivate* frameLoadDelegatePrivate)
{
return m_webViewPrivate->setFrameLoadDelegatePrivate(frameLoadDelegatePrivate);
}
HRESULT WebKitLegacyBrowserWindow::setUIDelegate(IWebUIDelegate* uiDelegate)
{
m_uiDelegate = uiDelegate;
return m_webView->setUIDelegate(uiDelegate);
}
HRESULT WebKitLegacyBrowserWindow::setAccessibilityDelegate(IAccessibilityDelegate* accessibilityDelegate)
{
m_accessibilityDelegate = accessibilityDelegate;
return m_webView->setAccessibilityDelegate(accessibilityDelegate);
}
HRESULT WebKitLegacyBrowserWindow::setResourceLoadDelegate(IWebResourceLoadDelegate* resourceLoadDelegate)
{
m_resourceLoadDelegate = resourceLoadDelegate;
return m_webView->setResourceLoadDelegate(resourceLoadDelegate);
}
HRESULT WebKitLegacyBrowserWindow::setDownloadDelegate(IWebDownloadDelegatePtr downloadDelegate)
{
m_downloadDelegate = downloadDelegate;
return m_webView->setDownloadDelegate(downloadDelegate);
}
IWebFramePtr WebKitLegacyBrowserWindow::mainFrame()
{
IWebFramePtr framePtr;
m_webView->mainFrame(&framePtr.GetInterfacePtr());
return framePtr;
}
bool WebKitLegacyBrowserWindow::seedInitialDefaultPreferences()
{
IWebPreferencesPtr tmpPreferences;
if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences.GetInterfacePtr()))))
return false;
if (FAILED(tmpPreferences->standardPreferences(&m_standardPreferences.GetInterfacePtr())))
return false;
return true;
}
bool WebKitLegacyBrowserWindow::setToDefaultPreferences()
{
HRESULT hr = m_standardPreferences->QueryInterface(IID_IWebPreferencesPrivate, reinterpret_cast<void**>(&m_prefsPrivate.GetInterfacePtr()));
if (!SUCCEEDED(hr))
return false;
#if USE(CG)
m_standardPreferences->setAVFoundationEnabled(TRUE);
m_prefsPrivate->setAcceleratedCompositingEnabled(TRUE);
#endif
m_prefsPrivate->setFullScreenEnabled(TRUE);
m_prefsPrivate->setShowDebugBorders(FALSE);
m_prefsPrivate->setShowRepaintCounter(FALSE);
m_prefsPrivate->setShouldInvertColors(FALSE);
m_standardPreferences->setLoadsImagesAutomatically(TRUE);
m_prefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
m_standardPreferences->setJavaScriptEnabled(TRUE);
m_prefsPrivate->setAllowUniversalAccessFromFileURLs(FALSE);
m_prefsPrivate->setAllowFileAccessFromFileURLs(TRUE);
m_prefsPrivate->setDeveloperExtrasEnabled(TRUE);
return true;
}
static void updateMenuItemForHistoryItem(HMENU menu, IWebHistoryItem& historyItem, int currentHistoryItem)
{
UINT menuID = IDM_HISTORY_LINK0 + currentHistoryItem;
MENUITEMINFO menuItemInfo { };
menuItemInfo.cbSize = sizeof(MENUITEMINFO);
menuItemInfo.fMask = MIIM_TYPE;
menuItemInfo.fType = MFT_STRING;
_bstr_t title;
historyItem.title(title.GetAddress());
menuItemInfo.dwTypeData = static_cast<LPWSTR>(title);
::SetMenuItemInfo(menu, menuID, FALSE, &menuItemInfo);
::EnableMenuItem(menu, menuID, MF_BYCOMMAND | MF_ENABLED);
}
void WebKitLegacyBrowserWindow::showLastVisitedSites(IWebView& webView)
{
HMENU menu = ::GetMenu(m_hMainWnd);
_com_ptr_t<_com_IIID<IWebBackForwardList, &__uuidof(IWebBackForwardList)>> backForwardList;
HRESULT hr = webView.backForwardList(&backForwardList.GetInterfacePtr());
if (FAILED(hr))
return;
int capacity = 0;
hr = backForwardList->capacity(&capacity);
if (FAILED(hr))
return;
int backCount = 0;
hr = backForwardList->backListCount(&backCount);
if (FAILED(hr))
return;
UINT backSetting = MF_BYCOMMAND | ((backCount) ? MF_ENABLED : MF_DISABLED);
::EnableMenuItem(menu, IDM_HISTORY_BACKWARD, backSetting);
int forwardCount = 0;
hr = backForwardList->forwardListCount(&forwardCount);
if (FAILED(hr))
return;
UINT forwardSetting = MF_BYCOMMAND | ((forwardCount) ? MF_ENABLED : MF_DISABLED);
::EnableMenuItem(menu, IDM_HISTORY_FORWARD, forwardSetting);
IWebHistoryItemPtr currentItem;
hr = backForwardList->currentItem(&currentItem.GetInterfacePtr());
if (FAILED(hr))
return;
hr = m_webHistory->addItems(1, &currentItem.GetInterfacePtr());
if (FAILED(hr))
return;
_com_ptr_t<_com_IIID<IWebHistoryPrivate, &__uuidof(IWebHistoryPrivate)>> webHistory;
hr = m_webHistory->QueryInterface(IID_IWebHistoryPrivate, reinterpret_cast<void**>(&webHistory.GetInterfacePtr()));
if (FAILED(hr))
return;
int totalListCount = 0;
hr = webHistory->allItems(&totalListCount, 0);
if (FAILED(hr))
return;
m_historyItems.resize(totalListCount);
std::vector<IWebHistoryItem*> historyToLoad(totalListCount);
hr = webHistory->allItems(&totalListCount, historyToLoad.data());
if (FAILED(hr))
return;
size_t i = 0;
for (auto& cur : historyToLoad) {
m_historyItems[i].Attach(cur);
++i;
}
int allItemsOffset = 0;
if (totalListCount > maxHistorySize)
allItemsOffset = totalListCount - maxHistorySize;
int currentHistoryItem = 0;
for (int i = 0; i < m_historyItems.size() && (allItemsOffset + currentHistoryItem) < m_historyItems.size(); ++i) {
updateMenuItemForHistoryItem(menu, *(m_historyItems[allItemsOffset + currentHistoryItem]), currentHistoryItem);
++currentHistoryItem;
}
// Hide any history we aren't using yet.
for (int i = currentHistoryItem; i < maxHistorySize; ++i)
::EnableMenuItem(menu, IDM_HISTORY_LINK0 + i, MF_BYCOMMAND | MF_DISABLED);
}
void WebKitLegacyBrowserWindow::launchInspector()
{
if (!m_webViewPrivate)
return;
if (!SUCCEEDED(m_webViewPrivate->inspector(&m_inspector.GetInterfacePtr())))
return;
m_inspector->show();
}
void WebKitLegacyBrowserWindow::openProxySettings()
{
}
void WebKitLegacyBrowserWindow::navigateForwardOrBackward(UINT menuID)
{
if (!m_webView)
return;
BOOL wentBackOrForward = FALSE;
if (IDM_HISTORY_FORWARD == menuID)
m_webView->goForward(&wentBackOrForward);
else
m_webView->goBack(&wentBackOrForward);
}
void WebKitLegacyBrowserWindow::navigateToHistory(UINT menuID)
{
if (!m_webView)
return;
int historyEntry = menuID - IDM_HISTORY_LINK0;
if (historyEntry > m_historyItems.size())
return;
IWebHistoryItemPtr desiredHistoryItem = m_historyItems[historyEntry];
if (!desiredHistoryItem)
return;
BOOL succeeded = FALSE;
m_webView->goToBackForwardItem(desiredHistoryItem, &succeeded);
_bstr_t frameURL;
desiredHistoryItem->URLString(frameURL.GetAddress());
::SendMessage(m_hURLBarWnd, (UINT)WM_SETTEXT, 0, (LPARAM)frameURL.GetBSTR());
}
bool WebKitLegacyBrowserWindow::goBack()
{
BOOL wentBack = FALSE;
m_webView->goBack(&wentBack);
return wentBack;
}
bool WebKitLegacyBrowserWindow::goForward()
{
BOOL wentForward = FALSE;
m_webView->goForward(&wentForward);
return wentForward;
}
HRESULT WebKitLegacyBrowserWindow::loadURL(const BSTR& passedURL)
{
if (!passedURL)
return E_INVALIDARG;
_bstr_t urlBStr(passedURL);
if (!!urlBStr && (::PathFileExists(urlBStr) || ::PathIsUNC(urlBStr))) {
TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
DWORD fileURLLength = sizeof(fileURL) / sizeof(fileURL[0]);
if (SUCCEEDED(::UrlCreateFromPath(urlBStr, fileURL, &fileURLLength, 0)))
urlBStr = fileURL;
}
IWebFramePtr frame;
HRESULT hr = m_webView->mainFrame(&frame.GetInterfacePtr());
if (FAILED(hr))
return hr;
IWebMutableURLRequestPtr request;
hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
if (FAILED(hr))
return hr;
hr = request->initWithURL(wcsstr(static_cast<wchar_t*>(urlBStr), L"://") ? urlBStr : _bstr_t(L"http://") + urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
if (FAILED(hr))
return hr;
_bstr_t methodBStr(L"GET");
hr = request->setHTTPMethod(methodBStr);
if (FAILED(hr))
return hr;
hr = frame->loadRequest(request);
return hr;
}
void WebKitLegacyBrowserWindow::exitProgram()
{
::PostMessage(m_hMainWnd, static_cast<UINT>(WM_COMMAND), MAKELPARAM(IDM_EXIT, 0), 0);
}
void WebKitLegacyBrowserWindow::setUserAgent(_bstr_t& customUserAgent)
{
if (!webView())
return;
webView()->setCustomUserAgent(customUserAgent.GetBSTR());
}
_bstr_t WebKitLegacyBrowserWindow::userAgent()
{
_bstr_t userAgent;
if (FAILED(webView()->customUserAgent(&userAgent.GetBSTR())))
return _bstr_t(L"- Unknown -: Call failed.");
return userAgent;
}
typedef _com_ptr_t<_com_IIID<IWebIBActions, &__uuidof(IWebIBActions)>> IWebIBActionsPtr;
void WebKitLegacyBrowserWindow::resetZoom()
{
IWebIBActionsPtr webActions;
if (FAILED(m_webView->QueryInterface(IID_IWebIBActions, reinterpret_cast<void**>(&webActions.GetInterfacePtr()))))
return;
webActions->resetPageZoom(nullptr);
}
void WebKitLegacyBrowserWindow::zoomIn()
{
IWebIBActionsPtr webActions;
if (FAILED(m_webView->QueryInterface(IID_IWebIBActions, reinterpret_cast<void**>(&webActions.GetInterfacePtr()))))
return;
webActions->zoomPageIn(nullptr);
}
void WebKitLegacyBrowserWindow::zoomOut()
{
IWebIBActionsPtr webActions;
if (FAILED(m_webView->QueryInterface(IID_IWebIBActions, reinterpret_cast<void**>(&webActions.GetInterfacePtr()))))
return;
webActions->zoomPageOut(nullptr);
}
typedef _com_ptr_t<_com_IIID<IWebViewPrivate3, &__uuidof(IWebViewPrivate3)>> IWebViewPrivate3Ptr;
void WebKitLegacyBrowserWindow::showLayerTree()
{
IWebViewPrivate3Ptr webViewPrivate;
if (FAILED(m_webView->QueryInterface(IID_IWebViewPrivate3, reinterpret_cast<void**>(&webViewPrivate.GetInterfacePtr()))))
return;
OutputDebugString(L"CURRENT TREE:\n");
_bstr_t layerTreeBstr;
if (FAILED(webViewPrivate->layerTreeAsString(layerTreeBstr.GetAddress())))
OutputDebugString(L" Failed to retrieve the layer tree.\n");
else
OutputDebugString(layerTreeBstr);
OutputDebugString(L"\n\n");
}
static BOOL CALLBACK AbortProc(HDC hDC, int Error)
{
MSG msg;
while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return TRUE;
}
static HDC getPrinterDC()
{
PRINTDLG pdlg;
memset(&pdlg, 0, sizeof(PRINTDLG));
pdlg.lStructSize = sizeof(PRINTDLG);
pdlg.Flags = PD_PRINTSETUP | PD_RETURNDC;
::PrintDlg(&pdlg);
return pdlg.hDC;
}
static void initDocStruct(DOCINFO* di, const wchar_t* docname)
{
memset(di, 0, sizeof(DOCINFO));
di->cbSize = sizeof(DOCINFO);
di->lpszDocName = docname;
}
void WebKitLegacyBrowserWindow::print()
{
HDC printDC = getPrinterDC();
if (!printDC) {
::MessageBox(0, L"Error creating printing DC", L"Error", MB_APPLMODAL | MB_OK);
return;
}
if (::SetAbortProc(printDC, AbortProc) == SP_ERROR) {
::MessageBox(0, L"Error setting up AbortProc", L"Error", MB_APPLMODAL | MB_OK);
return;
}
IWebFramePtr frame = mainFrame();
if (!frame)
return;
IWebFramePrivatePtr framePrivate;
if (FAILED(frame->QueryInterface(&framePrivate.GetInterfacePtr())))
return;
framePrivate->setInPrintingMode(TRUE, printDC);
UINT pageCount = 0;
framePrivate->getPrintedPageCount(printDC, &pageCount);
DOCINFO di;
initDocStruct(&di, L"WebKit Doc");
::StartDoc(printDC, &di);
// FIXME: Need CoreGraphics implementation
void* graphicsContext = 0;
for (size_t page = 1; page <= pageCount; ++page) {
::StartPage(printDC);
framePrivate->spoolPages(printDC, page, page, graphicsContext);
::EndPage(printDC);
}
framePrivate->setInPrintingMode(FALSE, printDC);
::EndDoc(printDC);
::DeleteDC(printDC);
}
static void setWindowText(HWND dialog, UINT field, _bstr_t value)
{
::SetDlgItemText(dialog, field, value);
}
static void setWindowText(HWND dialog, UINT field, UINT value)
{
String valueStr = WTF::String::number(value);
setWindowText(dialog, field, _bstr_t(valueStr.utf8().data()));
}
typedef _com_ptr_t<_com_IIID<IPropertyBag, &__uuidof(IPropertyBag)>> IPropertyBagPtr;
static void setWindowText(HWND dialog, UINT field, IPropertyBagPtr statistics, const _bstr_t& key)
{
_variant_t var;
V_VT(&var) = VT_UI8;
if (FAILED(statistics->Read(key, &var.GetVARIANT(), nullptr)))
return;
unsigned long long value = V_UI8(&var);
String valueStr = WTF::String::number(value);
setWindowText(dialog, field, _bstr_t(valueStr.utf8().data()));
}
static void setWindowText(HWND dialog, UINT field, CFDictionaryRef dictionary, CFStringRef key, UINT& total)
{
CFNumberRef countNum = static_cast<CFNumberRef>(CFDictionaryGetValue(dictionary, key));
if (!countNum)
return;
int count = 0;
CFNumberGetValue(countNum, kCFNumberIntType, &count);
setWindowText(dialog, field, static_cast<UINT>(count));
total += count;
}
void WebKitLegacyBrowserWindow::updateStatistics(HWND dialog)
{
IWebCoreStatisticsPtr webCoreStatistics = statistics();
if (!webCoreStatistics)
return;
IPropertyBagPtr statistics;
HRESULT hr = webCoreStatistics->memoryStatistics(&statistics.GetInterfacePtr());
if (FAILED(hr))
return;
// FastMalloc.
setWindowText(dialog, IDC_RESERVED_VM, statistics, "FastMallocReservedVMBytes");
setWindowText(dialog, IDC_COMMITTED_VM, statistics, "FastMallocCommittedVMBytes");
setWindowText(dialog, IDC_FREE_LIST_BYTES, statistics, "FastMallocFreeListBytes");
// WebCore Cache.
#if USE(CF)
IWebCachePtr webCache = this->webCache();
int dictCount = 6;
IPropertyBag* cacheDict[6] = { 0 };
if (FAILED(webCache->statistics(&dictCount, cacheDict)))
return;
COMPtr<CFDictionaryPropertyBag> counts, sizes, liveSizes, decodedSizes, purgableSizes;
counts.adoptRef(reinterpret_cast<CFDictionaryPropertyBag*>(cacheDict[0]));
sizes.adoptRef(reinterpret_cast<CFDictionaryPropertyBag*>(cacheDict[1]));
liveSizes.adoptRef(reinterpret_cast<CFDictionaryPropertyBag*>(cacheDict[2]));
decodedSizes.adoptRef(reinterpret_cast<CFDictionaryPropertyBag*>(cacheDict[3]));
purgableSizes.adoptRef(reinterpret_cast<CFDictionaryPropertyBag*>(cacheDict[4]));
static CFStringRef imagesKey = CFSTR("images");
static CFStringRef stylesheetsKey = CFSTR("style sheets");
static CFStringRef xslKey = CFSTR("xsl");
static CFStringRef scriptsKey = CFSTR("scripts");
if (counts) {
UINT totalObjects = 0;
setWindowText(dialog, IDC_IMAGES_OBJECT_COUNT, counts->dictionary(), imagesKey, totalObjects);
setWindowText(dialog, IDC_CSS_OBJECT_COUNT, counts->dictionary(), stylesheetsKey, totalObjects);
setWindowText(dialog, IDC_XSL_OBJECT_COUNT, counts->dictionary(), xslKey, totalObjects);
setWindowText(dialog, IDC_JSC_OBJECT_COUNT, counts->dictionary(), scriptsKey, totalObjects);
setWindowText(dialog, IDC_TOTAL_OBJECT_COUNT, totalObjects);
}
if (sizes) {
UINT totalBytes = 0;
setWindowText(dialog, IDC_IMAGES_BYTES, sizes->dictionary(), imagesKey, totalBytes);
setWindowText(dialog, IDC_CSS_BYTES, sizes->dictionary(), stylesheetsKey, totalBytes);
setWindowText(dialog, IDC_XSL_BYTES, sizes->dictionary(), xslKey, totalBytes);
setWindowText(dialog, IDC_JSC_BYTES, sizes->dictionary(), scriptsKey, totalBytes);
setWindowText(dialog, IDC_TOTAL_BYTES, totalBytes);
}
if (liveSizes) {
UINT totalLiveBytes = 0;
setWindowText(dialog, IDC_IMAGES_LIVE_COUNT, liveSizes->dictionary(), imagesKey, totalLiveBytes);
setWindowText(dialog, IDC_CSS_LIVE_COUNT, liveSizes->dictionary(), stylesheetsKey, totalLiveBytes);
setWindowText(dialog, IDC_XSL_LIVE_COUNT, liveSizes->dictionary(), xslKey, totalLiveBytes);
setWindowText(dialog, IDC_JSC_LIVE_COUNT, liveSizes->dictionary(), scriptsKey, totalLiveBytes);
setWindowText(dialog, IDC_TOTAL_LIVE_COUNT, totalLiveBytes);
}
if (decodedSizes) {
UINT totalDecoded = 0;
setWindowText(dialog, IDC_IMAGES_DECODED_COUNT, decodedSizes->dictionary(), imagesKey, totalDecoded);
setWindowText(dialog, IDC_CSS_DECODED_COUNT, decodedSizes->dictionary(), stylesheetsKey, totalDecoded);
setWindowText(dialog, IDC_XSL_DECODED_COUNT, decodedSizes->dictionary(), xslKey, totalDecoded);
setWindowText(dialog, IDC_JSC_DECODED_COUNT, decodedSizes->dictionary(), scriptsKey, totalDecoded);
setWindowText(dialog, IDC_TOTAL_DECODED, totalDecoded);
}
if (purgableSizes) {
UINT totalPurgable = 0;
setWindowText(dialog, IDC_IMAGES_PURGEABLE_COUNT, purgableSizes->dictionary(), imagesKey, totalPurgable);
setWindowText(dialog, IDC_CSS_PURGEABLE_COUNT, purgableSizes->dictionary(), stylesheetsKey, totalPurgable);
setWindowText(dialog, IDC_XSL_PURGEABLE_COUNT, purgableSizes->dictionary(), xslKey, totalPurgable);
setWindowText(dialog, IDC_JSC_PURGEABLE_COUNT, purgableSizes->dictionary(), scriptsKey, totalPurgable);
setWindowText(dialog, IDC_TOTAL_PURGEABLE, totalPurgable);
}
#endif
// JavaScript Heap.
setWindowText(dialog, IDC_JSC_HEAP_SIZE, statistics, "JavaScriptHeapSize");
setWindowText(dialog, IDC_JSC_HEAP_FREE, statistics, "JavaScriptFreeSize");
UINT count;
if (SUCCEEDED(webCoreStatistics->javaScriptObjectsCount(&count)))
setWindowText(dialog, IDC_TOTAL_JSC_HEAP_OBJECTS, count);
if (SUCCEEDED(webCoreStatistics->javaScriptGlobalObjectsCount(&count)))
setWindowText(dialog, IDC_GLOBAL_JSC_HEAP_OBJECTS, count);
if (SUCCEEDED(webCoreStatistics->javaScriptProtectedObjectsCount(&count)))
setWindowText(dialog, IDC_PROTECTED_JSC_HEAP_OBJECTS, count);
// Font and Glyph Caches.
if (SUCCEEDED(webCoreStatistics->cachedFontDataCount(&count)))
setWindowText(dialog, IDC_TOTAL_FONT_OBJECTS, count);
if (SUCCEEDED(webCoreStatistics->cachedFontDataInactiveCount(&count)))
setWindowText(dialog, IDC_INACTIVE_FONT_OBJECTS, count);
if (SUCCEEDED(webCoreStatistics->glyphPageCount(&count)))
setWindowText(dialog, IDC_GLYPH_PAGES, count);
// Site Icon Database.
if (SUCCEEDED(webCoreStatistics->iconPageURLMappingCount(&count)))
setWindowText(dialog, IDC_PAGE_URL_MAPPINGS, count);
if (SUCCEEDED(webCoreStatistics->iconRetainedPageURLCount(&count)))
setWindowText(dialog, IDC_RETAINED_PAGE_URLS, count);
if (SUCCEEDED(webCoreStatistics->iconRecordCount(&count)))
setWindowText(dialog, IDC_SITE_ICON_RECORDS, count);
if (SUCCEEDED(webCoreStatistics->iconsWithDataCount(&count)))
setWindowText(dialog, IDC_SITE_ICONS_WITH_DATA, count);
}
void WebKitLegacyBrowserWindow::setPreference(UINT menuID, bool enable)
{
if (!standardPreferences() || !privatePreferences())
return;
switch (menuID) {
case IDM_AVFOUNDATION:
standardPreferences()->setAVFoundationEnabled(enable);
break;
case IDM_ACC_COMPOSITING:
privatePreferences()->setAcceleratedCompositingEnabled(enable);
break;
case IDM_WK_FULLSCREEN:
privatePreferences()->setFullScreenEnabled(enable);
break;
case IDM_COMPOSITING_BORDERS:
privatePreferences()->setShowDebugBorders(enable);
privatePreferences()->setShowRepaintCounter(enable);
break;
case IDM_DEBUG_INFO_LAYER:
privatePreferences()->setShowTiledScrollingIndicator(enable);
break;
case IDM_INVERT_COLORS:
privatePreferences()->setShouldInvertColors(enable);
break;
case IDM_DISABLE_IMAGES:
standardPreferences()->setLoadsImagesAutomatically(!enable);
break;
case IDM_DISABLE_STYLES:
privatePreferences()->setAuthorAndUserStylesEnabled(!enable);
break;
case IDM_DISABLE_JAVASCRIPT:
standardPreferences()->setJavaScriptEnabled(!enable);
break;
case IDM_DISABLE_LOCAL_FILE_RESTRICTIONS:
privatePreferences()->setAllowUniversalAccessFromFileURLs(enable);
privatePreferences()->setAllowFileAccessFromFileURLs(enable);
break;
}
}