1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "StdAfx.h"
27#include "BrowserView.h"
28
29#include "BrowserWindow.h"
30#include <WebKit2/WKContextPrivate.h>
31#include <WebKit2/WKURLCF.h>
32
33static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
34
35BrowserView::BrowserView()
36    : m_webView(0)
37{
38}
39
40// UI Client Callbacks
41
42static WKPageRef createNewPage(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void* clientInfo)
43{
44    BrowserWindow* browserWindow = BrowserWindow::create();
45    browserWindow->createWindow(0, 0, 800, 600);
46
47    return WKViewGetPage(browserWindow->view().webView());
48}
49
50static void showPage(WKPageRef page, const void *clientInfo)
51{
52    static_cast<BrowserWindow*>(const_cast<void*>(clientInfo))->showWindow();
53}
54
55static void closePage(WKPageRef page, const void *clientInfo)
56{
57}
58
59static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo)
60{
61}
62
63static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef frame, const void* clientInfo)
64{
65    return false;
66}
67
68static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void* clientInfo)
69{
70    return 0;
71}
72
73static void setStatusText(WKPageRef page, WKStringRef text, const void* clientInfo)
74{
75}
76
77static void mouseDidMoveOverElement(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo)
78{
79}
80
81void BrowserView::create(RECT webViewRect, BrowserWindow* parentWindow)
82{
83    assert(!m_webView);
84
85    bool isShiftKeyDown = ::GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT;
86
87    WKContextRef context;
88    if (isShiftKeyDown)
89        context = WKContextGetSharedThreadContext();
90    else
91        context = WKContextGetSharedProcessContext();
92
93    m_webView = WKViewCreate(webViewRect, context, 0, parentWindow->window());
94
95    WKPageUIClient uiClient = {
96        0,              /* version */
97        parentWindow,   /* clientInfo */
98        createNewPage,
99        showPage,
100        closePage,
101        0,          /* takeFocus */
102        0,          /* focus */
103        0,          /* unfocus */
104        runJavaScriptAlert,
105        runJavaScriptConfirm,
106        runJavaScriptPrompt,
107        setStatusText,
108        mouseDidMoveOverElement,
109        0,          /* didNotHandleKeyEvent */
110        0,          /* toolbarsAreVisible */
111        0,          /* setToolbarsAreVisible */
112        0,          /* menuBarIsVisible */
113        0,          /* setMenuBarIsVisible */
114        0,          /* statusBarIsVisible */
115        0,          /* setStatusBarIsVisible */
116        0,          /* isResizable */
117        0,          /* setIsResizable */
118        0,          /* getWindowFrame */
119        0,          /* setWindowFrame */
120        0,          /* runBeforeUnloadConfirmPanel */
121        0,          /* didDraw */
122        0,          /* pageDidScroll */
123        0,          /* exceededDatabaseQuota */
124        0,          /* runOpenPanel */
125        0,          /* decidePolicyForGeolocationPermissionRequest */
126    };
127
128    WKPageSetPageUIClient(WKViewGetPage(m_webView), &uiClient);
129
130    WKViewSetIsInWindow(m_webView, true);
131}
132
133void BrowserView::setFrame(RECT rect)
134{
135    HWND webViewWindow = WKViewGetWindow(m_webView);
136    ::SetWindowPos(webViewWindow, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
137}
138
139void BrowserView::goToURL(const std::wstring& urlString)
140{
141    CFStringRef string = CFStringCreateWithCharacters(0, (const UniChar*)urlString.data(), urlString.size());
142    CFURLRef cfURL = CFURLCreateWithString(0, string, 0);
143    CFRelease(string);
144
145    WKURLRef url = WKURLCreateWithCFURL(cfURL);
146    CFRelease(cfURL);
147
148    WKPageRef page = WKViewGetPage(m_webView);
149    WKPageLoadURL(page, url);
150    WKRelease(url);
151}
152