[Windows WebKit2] Use cookies set in WebKit1
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / win / WebPageWin.cpp
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 "config.h"
27 #include "WebPage.h"
28
29 #include "FontSmoothingLevel.h"
30 #include "WebCoreArgumentCoders.h"
31 #include "WebEvent.h"
32 #include "WebPageProxyMessages.h"
33 #include "WebPreferencesStore.h"
34 #include "WebProcess.h"
35 #include "WindowGeometry.h"
36 #include <WebCore/FocusController.h>
37 #include <WebCore/FontRenderingMode.h>
38 #include <WebCore/Frame.h>
39 #include <WebCore/FrameView.h>
40 #include <WebCore/HitTestRequest.h>
41 #include <WebCore/HitTestResult.h>
42 #include <WebCore/KeyboardEvent.h>
43 #include <WebCore/Page.h>
44 #include <WebCore/PlatformKeyboardEvent.h>
45 #include <WebCore/RenderLayer.h>
46 #include <WebCore/RenderView.h>
47 #include <WebCore/ResourceHandle.h>
48 #include <WebCore/Settings.h>
49 #if USE(CG)
50 #include <WebKitSystemInterface/WebKitSystemInterface.h>
51 #endif
52 #include <WinUser.h>
53
54 #if USE(CFNETWORK)
55 #include <CFNetwork/CFURLCachePriv.h>
56 #include <CFNetwork/CFURLProtocolPriv.h>
57 #include <CFNetwork/CFURLRequestPriv.h>
58 #endif
59
60 using namespace WebCore;
61
62 namespace WebKit {
63
64 void WebPage::platformInitialize()
65 {
66 }
67
68 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
69 {
70     FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey()));
71
72 #if USE(CG)
73     FontSmoothingLevel adjustedLevel = fontSmoothingLevel;
74     if (adjustedLevel == FontSmoothingLevelWindows)
75         adjustedLevel = FontSmoothingLevelMedium;
76     wkSetFontSmoothingLevel(adjustedLevel);
77 #endif
78
79     m_page->settings()->setFontRenderingMode(fontSmoothingLevel == FontSmoothingLevelWindows ? AlternateRenderingMode : NormalRenderingMode);
80 }
81
82 static const unsigned CtrlKey = 1 << 0;
83 static const unsigned AltKey = 1 << 1;
84 static const unsigned ShiftKey = 1 << 2;
85
86 struct KeyDownEntry {
87     unsigned virtualKey;
88     unsigned modifiers;
89     const char* name;
90 };
91
92 struct KeyPressEntry {
93     unsigned charCode;
94     unsigned modifiers;
95     const char* name;
96 };
97
98 static const KeyDownEntry keyDownEntries[] = {
99     { VK_LEFT,   0,                  "MoveLeft"                                    },
100     { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
101     { VK_LEFT,   CtrlKey,            "MoveWordLeft"                                },
102     { VK_LEFT,   CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection"              },
103     { VK_RIGHT,  0,                  "MoveRight"                                   },
104     { VK_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"                 },
105     { VK_RIGHT,  CtrlKey,            "MoveWordRight"                               },
106     { VK_RIGHT,  CtrlKey | ShiftKey, "MoveWordRightAndModifySelection"             },
107     { VK_UP,     0,                  "MoveUp"                                      },
108     { VK_UP,     ShiftKey,           "MoveUpAndModifySelection"                    },
109     { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
110     { VK_DOWN,   0,                  "MoveDown"                                    },
111     { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
112     { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
113     { VK_PRIOR,  0,                  "MovePageUp"                                  },
114     { VK_NEXT,   0,                  "MovePageDown"                                },
115     { VK_HOME,   0,                  "MoveToBeginningOfLine"                       },
116     { VK_HOME,   ShiftKey,           "MoveToBeginningOfLineAndModifySelection"     },
117     { VK_HOME,   CtrlKey,            "MoveToBeginningOfDocument"                   },
118     { VK_HOME,   CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
119
120     { VK_END,    0,                  "MoveToEndOfLine"                             },
121     { VK_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"           },
122     { VK_END,    CtrlKey,            "MoveToEndOfDocument"                         },
123     { VK_END,    CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection"       },
124
125     { VK_BACK,   0,                  "DeleteBackward"                              },
126     { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
127     { VK_DELETE, 0,                  "DeleteForward"                               },
128     { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
129     { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
130     
131     { 'B',       CtrlKey,            "ToggleBold"                                  },
132     { 'I',       CtrlKey,            "ToggleItalic"                                },
133
134     { VK_ESCAPE, 0,                  "Cancel"                                      },
135     { VK_OEM_PERIOD, CtrlKey,        "Cancel"                                      },
136     { VK_TAB,    0,                  "InsertTab"                                   },
137     { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
138     { VK_RETURN, 0,                  "InsertNewline"                               },
139     { VK_RETURN, CtrlKey,            "InsertNewline"                               },
140     { VK_RETURN, AltKey,             "InsertNewline"                               },
141     { VK_RETURN, ShiftKey,           "InsertNewline"                               },
142     { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
143
144     // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
145     // in the application or in WebKit. We chose WebKit.
146     { 'C',       CtrlKey,            "Copy"                                        },
147     { 'V',       CtrlKey,            "Paste"                                       },
148     { 'X',       CtrlKey,            "Cut"                                         },
149     { 'A',       CtrlKey,            "SelectAll"                                   },
150     { VK_INSERT, CtrlKey,            "Copy"                                        },
151     { VK_DELETE, ShiftKey,           "Cut"                                         },
152     { VK_INSERT, ShiftKey,           "Paste"                                       },
153     { 'Z',       CtrlKey,            "Undo"                                        },
154     { 'Z',       CtrlKey | ShiftKey, "Redo"                                        },
155 };
156
157 static const KeyPressEntry keyPressEntries[] = {
158     { '\t',   0,                  "InsertTab"                                   },
159     { '\t',   ShiftKey,           "InsertBacktab"                               },
160     { '\r',   0,                  "InsertNewline"                               },
161     { '\r',   CtrlKey,            "InsertNewline"                               },
162     { '\r',   AltKey,             "InsertNewline"                               },
163     { '\r',   ShiftKey,           "InsertNewline"                               },
164     { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
165 };
166
167 const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt)
168 {
169     ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
170
171     static HashMap<int, const char*>* keyDownCommandsMap = 0;
172     static HashMap<int, const char*>* keyPressCommandsMap = 0;
173
174     if (!keyDownCommandsMap) {
175         keyDownCommandsMap = new HashMap<int, const char*>;
176         keyPressCommandsMap = new HashMap<int, const char*>;
177
178         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i)
179             keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
180
181         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i)
182             keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
183     }
184
185     unsigned modifiers = 0;
186     if (evt->shiftKey())
187         modifiers |= ShiftKey;
188     if (evt->altKey())
189         modifiers |= AltKey;
190     if (evt->ctrlKey())
191         modifiers |= CtrlKey;
192
193     if (evt->type() == eventNames().keydownEvent) {
194         int mapKey = modifiers << 16 | evt->keyCode();
195         return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
196     }
197
198     int mapKey = modifiers << 16 | evt->charCode();
199     return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
200 }
201
202 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
203 {
204     if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown)
205         return false;
206
207     switch (keyboardEvent.windowsVirtualKeyCode()) {
208     case VK_BACK:
209         if (keyboardEvent.isSystemKey())
210             return false;
211         if (keyboardEvent.shiftKey())
212             m_page->goForward();
213         else
214             m_page->goBack();
215         break;
216     case VK_LEFT:
217         if (keyboardEvent.isSystemKey())
218             m_page->goBack();
219         else
220             scroll(m_page.get(), ScrollLeft, ScrollByLine);
221         break;
222     case VK_RIGHT:
223         if (keyboardEvent.isSystemKey())
224             m_page->goForward();
225         else
226             scroll(m_page.get(), ScrollRight, ScrollByLine);
227         break;
228     case VK_UP:
229         if (keyboardEvent.isSystemKey())
230             return false;
231         scroll(m_page.get(), ScrollUp, ScrollByLine);
232         break;
233     case VK_DOWN:
234         if (keyboardEvent.isSystemKey())
235             return false;
236         scroll(m_page.get(), ScrollDown, ScrollByLine);
237         break;
238     case VK_HOME:
239         if (keyboardEvent.isSystemKey())
240             return false;
241         logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument);
242         break;
243     case VK_END:
244         if (keyboardEvent.isSystemKey())
245             return false;
246         logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument);
247         break;
248     case VK_PRIOR:
249         if (keyboardEvent.isSystemKey())
250             return false;
251         logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
252         break;
253     case VK_NEXT:
254         if (keyboardEvent.isSystemKey())
255             return false;
256         logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
257         break;
258     default:
259         return false;
260     }
261
262     return true;
263 }
264
265 #if USE(CFNETWORK)
266 static RetainPtr<CFCachedURLResponseRef> cachedResponseForURL(WebPage* webPage, const KURL& url)
267 {
268     RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL());
269     RetainPtr<CFMutableURLRequestRef> request(AdoptCF, CFURLRequestCreateMutable(0, cfURL.get(), kCFURLRequestCachePolicyReloadIgnoringCache, 60, 0));
270 #if USE(CFURLSTORAGESESSIONS)
271     wkSetRequestStorageSession(ResourceHandle::currentStorageSession(), request.get());
272 #endif
273
274     RetainPtr<CFStringRef> userAgent(AdoptCF, webPage->userAgent().createCFString());
275     CFURLRequestSetHTTPHeaderFieldValue(request.get(), CFSTR("User-Agent"), userAgent.get());
276
277     RetainPtr<CFURLCacheRef> cache;
278 #if USE(CFURLSTORAGESESSIONS)
279     if (CFURLStorageSessionRef currentStorageSession = ResourceHandle::currentStorageSession())
280         cache.adoptCF(wkCopyURLCache(currentStorageSession));
281     else
282 #endif
283         cache.adoptCF(CFURLCacheCopySharedURLCache());
284
285     RetainPtr<CFCachedURLResponseRef> response(AdoptCF, CFURLCacheCopyResponseForRequest(cache.get(), request.get()));
286     return response;        
287 }
288 #endif
289
290 bool WebPage::platformHasLocalDataForURL(const KURL& url)
291 {
292 #if USE(CFNETWORK)
293     return cachedResponseForURL(this, url);
294 #else
295     return false;
296 #endif
297 }
298
299 String WebPage::cachedResponseMIMETypeForURL(const KURL& url)
300 {
301 #if USE(CFNETWORK)
302     RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
303     CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get());
304     return response ? CFURLResponseGetMIMEType(response) : String();
305 #else
306     return String();
307 #endif
308 }
309
310 String WebPage::cachedSuggestedFilenameForURL(const KURL& url)
311 {
312 #if USE(CFNETWORK)
313     RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
314     CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get());
315     if (!response)
316         return String();
317     RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(response));
318
319     return suggestedFilename.get();
320 #else
321     return String();
322 #endif
323 }
324
325 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL& url)
326 {
327 #if USE(CFNETWORK)
328     RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url);
329     CFDataRef data = CFCachedURLResponseGetReceiverData(cachedResponse.get());
330     if (!data)
331         return 0;
332
333     return SharedBuffer::wrapCFData(data);
334 #else
335     return 0;
336 #endif
337 }
338
339 bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request)
340 {
341 #if USE(CFNETWORK)
342     return CFURLProtocolCanHandleRequest(request.cfURLRequest());
343 #else
344     return true;
345 #endif
346 }
347
348 void WebPage::confirmComposition(const String& compositionString)
349 {
350     Frame* frame = m_page->focusController()->focusedOrMainFrame();
351     if (!frame || !frame->editor()->canEdit())
352         return;
353     frame->editor()->confirmComposition(compositionString);
354 }
355
356 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
357 {
358     Frame* frame = m_page->focusController()->focusedOrMainFrame();
359     if (!frame || !frame->editor()->canEdit())
360         return;
361     frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
362 }
363
364 void WebPage::firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect)
365 {
366     Frame* frame = m_page->focusController()->focusedOrMainFrame();
367     IntRect rect;
368     if (RefPtr<Range> range = frame->editor()->hasComposition() ? frame->editor()->compositionRange() : frame->selection()->selection().toNormalizedRange()) {
369         ExceptionCode ec = 0;
370         RefPtr<Range> tempRange = range->cloneRange(ec);
371         tempRange->setStart(tempRange->startContainer(ec), tempRange->startOffset(ec) + characterPosition, ec);
372         rect = frame->editor()->firstRectForRange(tempRange.get());
373     }
374     resultRect = frame->view()->contentsToWindow(rect);
375 }
376
377 void WebPage::getSelectedText(String& text)
378 {
379     Frame* frame = m_page->focusController()->focusedOrMainFrame();
380     RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
381     text = selectedRange->text();
382 }
383
384 void WebPage::gestureWillBegin(const WebCore::IntPoint& point, bool& canBeginPanning)
385 {
386     m_gestureReachedScrollingLimit = false;
387
388     bool hitScrollbar = false;
389
390     HitTestRequest request(HitTestRequest::ReadOnly);
391     for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) {
392         ScrollView* scollView = childFrame->view();
393         if (!scollView)
394             break;
395         
396         RenderView* renderView = childFrame->document()->renderView();
397         if (!renderView)
398             break;
399
400         RenderLayer* layer = renderView->layer();
401         if (!layer)
402             break;
403
404         HitTestResult result = scollView->windowToContents(point);
405         layer->hitTest(request, result);
406         m_gestureTargetNode = result.innerNode();
407
408         if (!hitScrollbar)
409             hitScrollbar = result.scrollbar();
410     }
411
412     if (hitScrollbar) {
413         canBeginPanning = false;
414         return;
415     }
416
417     if (!m_gestureTargetNode) {
418         canBeginPanning = false;
419         return;
420     }
421
422     for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) {
423         if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
424             canBeginPanning = true;
425             return;
426         }
427     }
428
429     canBeginPanning = false;
430 }
431
432 static bool scrollbarAtTopOrBottomOfDocument(Scrollbar* scrollbar)
433 {
434     ASSERT_ARG(scrollbar, scrollbar);
435     return !scrollbar->currentPos() || scrollbar->currentPos() >= scrollbar->maximum();
436 }
437
438 void WebPage::gestureDidScroll(const IntSize& size)
439 {
440     ASSERT_ARG(size, !size.isZero());
441
442     if (!m_gestureTargetNode || !m_gestureTargetNode->renderer() || !m_gestureTargetNode->renderer()->enclosingLayer())
443         return;
444
445     Scrollbar* verticalScrollbar = 0;
446     if (Frame* frame = m_page->mainFrame()) {
447         if (ScrollView* view = frame->view())
448             verticalScrollbar = view->verticalScrollbar();
449     }
450
451     m_gestureTargetNode->renderer()->enclosingLayer()->scrollByRecursively(size.width(), size.height());
452     bool gestureReachedScrollingLimit = verticalScrollbar && scrollbarAtTopOrBottomOfDocument(verticalScrollbar);
453
454     // FIXME: We really only want to update this state if the state was updated via scrolling the main frame,
455     // not scrolling something in a main frame when the main frame had already reached its scrolling limit.
456
457     if (gestureReachedScrollingLimit == m_gestureReachedScrollingLimit)
458         return;
459
460     send(Messages::WebPageProxy::SetGestureReachedScrollingLimit(gestureReachedScrollingLimit));
461     m_gestureReachedScrollingLimit = gestureReachedScrollingLimit;
462 }
463
464 void WebPage::gestureDidEnd()
465 {
466     m_gestureTargetNode = nullptr;
467 }
468
469 void WebPage::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
470 {
471     WebProcess::shared().connection()->send(Messages::WebPageProxy::ScheduleChildWindowGeometryUpdate(geometry), m_pageID);
472 }
473
474 } // namespace WebKit