1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4 * Copyright (C) 2011 Igalia S.L.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 * THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "config.h"
29#include "WebPage.h"
30
31#include "EditorState.h"
32#include "EventHandler.h"
33#include "NotImplemented.h"
34#include "WebEvent.h"
35#include "WindowsKeyboardCodes.h"
36#include <WebCore/EflKeyboardUtilities.h>
37#include <WebCore/FocusController.h>
38#include <WebCore/Frame.h>
39#include <WebCore/FrameView.h>
40#include <WebCore/KeyboardEvent.h>
41#include <WebCore/Page.h>
42#include <WebCore/PlatformKeyboardEvent.h>
43#include <WebCore/RenderThemeEfl.h>
44#include <WebCore/Settings.h>
45
46#if HAVE(ACCESSIBILITY)
47#include "WebPageAccessibilityObject.h"
48#endif
49
50using namespace WebCore;
51
52namespace WebKit {
53
54void WebPage::platformInitialize()
55{
56#if HAVE(ACCESSIBILITY)
57    m_accessibilityObject = adoptGRef(webPageAccessibilityObjectNew(this));
58#else
59    notImplemented();
60#endif
61}
62
63#if HAVE(ACCESSIBILITY)
64void WebPage::updateAccessibilityTree()
65{
66    if (!m_accessibilityObject)
67        return;
68
69    webPageAccessibilityObjectRefresh(m_accessibilityObject.get());
70}
71#endif
72
73void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
74{
75    notImplemented();
76}
77
78static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
79{
80    page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
81}
82
83bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
84{
85    if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown)
86        return false;
87
88    switch (keyboardEvent.windowsVirtualKeyCode()) {
89    case VK_BACK:
90        if (keyboardEvent.shiftKey())
91            m_page->goForward();
92        else
93            m_page->goBack();
94        break;
95    case VK_SPACE:
96        scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage);
97        break;
98    case VK_LEFT:
99        scroll(m_page.get(), ScrollLeft, ScrollByLine);
100        break;
101    case VK_RIGHT:
102        scroll(m_page.get(), ScrollRight, ScrollByLine);
103        break;
104    case VK_UP:
105        scroll(m_page.get(), ScrollUp, ScrollByLine);
106        break;
107    case VK_DOWN:
108        scroll(m_page.get(), ScrollDown, ScrollByLine);
109        break;
110    case VK_HOME:
111        scroll(m_page.get(), ScrollUp, ScrollByDocument);
112        break;
113    case VK_END:
114        scroll(m_page.get(), ScrollDown, ScrollByDocument);
115        break;
116    case VK_PRIOR:
117        scroll(m_page.get(), ScrollUp, ScrollByPage);
118        break;
119    case VK_NEXT:
120        scroll(m_page.get(), ScrollDown, ScrollByPage);
121        break;
122    default:
123        return false;
124    }
125
126    return true;
127}
128
129bool WebPage::platformHasLocalDataForURL(const KURL&)
130{
131    notImplemented();
132    return false;
133}
134
135String WebPage::cachedResponseMIMETypeForURL(const KURL&)
136{
137    notImplemented();
138    return String();
139}
140
141bool WebPage::platformCanHandleRequest(const ResourceRequest&)
142{
143    notImplemented();
144    return true;
145}
146
147String WebPage::cachedSuggestedFilenameForURL(const KURL&)
148{
149    notImplemented();
150    return String();
151}
152
153PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
154{
155    notImplemented();
156    return 0;
157}
158
159const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
160{
161    ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
162
163    if (event->type() == eventNames().keydownEvent)
164        return getKeyDownCommandName(event);
165
166    return getKeyPressCommandName(event);
167}
168
169void WebPage::setThemePath(const String& themePath)
170{
171    WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
172    theme->setThemePath(themePath);
173}
174
175static Frame* targetFrameForEditing(WebPage* page)
176{
177    Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
178    if (!frame)
179        return 0;
180
181    Editor& editor = frame->editor();
182    if (!editor.canEdit())
183        return 0;
184
185    if (editor.hasComposition()) {
186        // We should verify the parent node of this IME composition node are
187        // editable because JavaScript may delete a parent node of the composition
188        // node. In this case, WebKit crashes while deleting texts from the parent
189        // node, which doesn't exist any longer.
190        if (PassRefPtr<Range> range = editor.compositionRange()) {
191            Node* node = range->startContainer();
192            if (!node || !node->isContentEditable())
193                return 0;
194        }
195    }
196
197    return frame;
198}
199
200void WebPage::confirmComposition(const String& compositionString)
201{
202    Frame* targetFrame = targetFrameForEditing(this);
203    if (!targetFrame)
204        return;
205
206    targetFrame->editor().confirmComposition(compositionString);
207}
208
209void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
210{
211    Frame* targetFrame = targetFrameForEditing(this);
212    if (!targetFrame)
213        return;
214
215    targetFrame->editor().setComposition(compositionString, underlines, cursorPosition, 0);
216}
217
218void WebPage::cancelComposition()
219{
220    Frame* frame = m_page->focusController()->focusedOrMainFrame();
221    if (!frame)
222        return;
223
224    frame->editor().cancelComposition();
225}
226
227} // namespace WebKit
228