447c0f97df308961a4de4303e6bb3a04462e1c52
[WebKit-https.git] / Source / WebKit2 / UIProcess / ios / WebPageProxyIOS.mm
1 /*
2  * Copyright (C) 2012 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 #import "config.h"
27 #import "WebPageProxy.h"
28
29 #import "NativeWebKeyboardEvent.h"
30 #import "PageClient.h"
31 #import "WKBrowsingContextControllerInternal.h"
32 #import "WebKitSystemInterfaceIOS.h"
33 #import "WebPageMessages.h"
34 #import "WebProcessProxy.h"
35 #import <WebCore/NotImplemented.h>
36 #import <WebCore/UserAgent.h>
37 #import <WebCore/SharedBuffer.h>
38
39 using namespace WebCore;
40
41 namespace WebKit {
42
43 void WebPageProxy::platformInitialize()
44 {
45 }
46
47 static String userVisibleWebKitVersionString()
48 {
49     // If the version is longer than 3 digits then the leading digits represent the version of the OS. Our user agent
50     // string should not include the leading digits, so strip them off and report the rest as the version. <rdar://problem/4997547>
51     NSString *fullVersion = [[NSBundle bundleForClass:NSClassFromString(@"WKView")] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
52     NSRange nonDigitRange = [fullVersion rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
53     if (nonDigitRange.location == NSNotFound && fullVersion.length > 3)
54         return [fullVersion substringFromIndex:fullVersion.length - 3];
55     if (nonDigitRange.location != NSNotFound && nonDigitRange.location > 3)
56         return [fullVersion substringFromIndex:nonDigitRange.location - 3];
57     return fullVersion;
58 }
59
60 String WebPageProxy::standardUserAgent(const String& applicationName)
61 {
62     return standardUserAgentWithApplicationName(applicationName, userVisibleWebKitVersionString());
63 }
64
65 void WebPageProxy::getIsSpeaking(bool&)
66 {
67     notImplemented();
68 }
69
70 void WebPageProxy::speak(const String&)
71 {
72     notImplemented();
73 }
74
75 void WebPageProxy::stopSpeaking()
76 {
77     notImplemented();
78 }
79
80 void WebPageProxy::searchWithSpotlight(const String&)
81 {
82     notImplemented();
83 }
84
85 void WebPageProxy::searchTheWeb(const String&)
86 {
87     notImplemented();
88 }
89
90 void WebPageProxy::windowAndViewFramesChanged(const FloatRect&, const FloatPoint&)
91 {
92     notImplemented();
93 }
94
95 void WebPageProxy::setComposition(const String& text, Vector<CompositionUnderline> underline, uint64_t selectionStart, uint64_t selectionEnd, uint64_t, uint64_t)
96 {
97     if (!isValid())
98         return;
99
100     process().send(Messages::WebPage::SetComposition(text, underline, selectionStart, selectionEnd), m_pageID);
101 }
102
103 void WebPageProxy::confirmComposition()
104 {
105     if (!isValid())
106         return;
107
108     process().send(Messages::WebPage::ConfirmComposition(), m_pageID);
109 }
110
111 void WebPageProxy::cancelComposition()
112 {
113     notImplemented();
114
115 }
116
117 bool WebPageProxy::insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd)
118 {
119     if (!isValid())
120         return true;
121     
122     process().send(Messages::WebPage::InsertText(text, replacementRangeStart, replacementRangeEnd), m_pageID);
123     return true;
124 }
125
126 bool WebPageProxy::insertDictatedText(const String&, uint64_t, uint64_t, const Vector<WebCore::TextAlternativeWithRange>&)
127 {
128     notImplemented();
129     return false;
130 }
131
132 void WebPageProxy::getMarkedRange(uint64_t&, uint64_t&)
133 {
134     notImplemented();
135 }
136
137 void WebPageProxy::getSelectedRange(uint64_t&, uint64_t&)
138 {
139     notImplemented();
140 }
141
142 void WebPageProxy::getAttributedSubstringFromRange(uint64_t, uint64_t, AttributedString&)
143 {
144     notImplemented();
145 }
146
147 uint64_t WebPageProxy::characterIndexForPoint(const IntPoint)
148 {
149     notImplemented();
150     return 0;
151 }
152
153 IntRect WebPageProxy::firstRectForCharacterRange(uint64_t, uint64_t)
154 {
155     notImplemented();
156     return IntRect();
157 }
158
159 bool WebPageProxy::executeKeypressCommands(const Vector<WebCore::KeypressCommand>&)
160 {
161     notImplemented();
162     return false;
163 }
164
165 String WebPageProxy::stringSelectionForPasteboard()
166 {
167     notImplemented();
168     return String();
169 }
170
171 PassRefPtr<WebCore::SharedBuffer> WebPageProxy::dataSelectionForPasteboard(const String&)
172 {
173     notImplemented();
174     return 0;
175 }
176
177 bool WebPageProxy::readSelectionFromPasteboard(const String&)
178 {
179     notImplemented();
180     return false;
181 }
182
183 void WebPageProxy::performDictionaryLookupAtLocation(const WebCore::FloatPoint&)
184 {
185     notImplemented();
186 }
187
188 void WebPageProxy::gestureCallback(const WebCore::IntPoint& point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, uint64_t callbackID)
189 {
190     RefPtr<GestureCallback> callback = m_gestureCallbacks.take(callbackID);
191     if (!callback) {
192         ASSERT_NOT_REACHED();
193         return;
194     }
195     
196     callback->performCallbackWithReturnValue(point, gestureType, gestureState, flags);
197 }
198
199 void WebPageProxy::touchesCallback(const WebCore::IntPoint& point, uint32_t touches, uint64_t callbackID)
200 {
201     RefPtr<TouchesCallback> callback = m_touchesCallbacks.take(callbackID);
202     if (!callback) {
203         ASSERT_NOT_REACHED();
204         return;
205     }
206
207     callback->performCallbackWithReturnValue(point, touches);
208 }
209
210 void WebPageProxy::autocorrectionDataCallback(const Vector<WebCore::FloatRect>& rects, const String& fontName, float fontSize, uint64_t fontTraits, uint64_t callbackID)
211 {
212     RefPtr<AutocorrectionDataCallback> callback = m_autocorrectionCallbacks.take(callbackID);
213     if (!callback) {
214         ASSERT_NOT_REACHED();
215         return;
216     }
217
218     callback->performCallbackWithReturnValue(rects, fontName, fontSize, fontTraits);
219 }
220
221 void WebPageProxy::autocorrectionContextCallback(const String& beforeText, const String& markedText, const String& selectedText, const String& afterText, uint64_t location, uint64_t length, uint64_t callbackID)
222 {
223     RefPtr<AutocorrectionContextCallback> callback = m_autocorrectionContextCallbacks.take(callbackID);
224     if (!callback) {
225         ASSERT_NOT_REACHED();
226         return;
227     }
228
229     callback->performCallbackWithReturnValue(beforeText, markedText, selectedText, afterText, location, length);
230 }
231
232 void WebPageProxy::selectWithGesture(const WebCore::IntPoint point, WebCore::TextGranularity granularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback> callback)
233 {
234     if (!isValid()) {
235         callback->invalidate();
236         return;
237     }
238     
239     uint64_t callbackID = callback->callbackID();
240     m_gestureCallbacks.set(callbackID, callback);
241     m_process->send(Messages::WebPage::SelectWithGesture(point, (uint32_t)granularity, gestureType, gestureState, callbackID), m_pageID);
242 }
243
244 void WebPageProxy::updateSelectionWithTouches(const WebCore::IntPoint point, uint32_t touches, bool baseIsStart, PassRefPtr<TouchesCallback> callback)
245 {
246     if (!isValid()) {
247         callback->invalidate();
248         return;
249     }
250
251     uint64_t callbackID = callback->callbackID();
252     m_touchesCallbacks.set(callbackID, callback);
253     m_process->send(Messages::WebPage::UpdateSelectionWithTouches(point, touches, baseIsStart, callbackID), m_pageID);
254 }
255
256 void WebPageProxy::requestAutocorrectionData(const String& textForAutocorrection, PassRefPtr<AutocorrectionDataCallback> callback)
257 {
258     if (!isValid()) {
259         callback->invalidate();
260         return;
261     }
262
263     uint64_t callbackID = callback->callbackID();
264     m_autocorrectionCallbacks.set(callbackID, callback);
265     m_process->send(Messages::WebPage::RequestAutocorrectionData(textForAutocorrection, callbackID), m_pageID);
266 }
267
268 void WebPageProxy::applyAutocorrection(const String& correction, const String& originalText, PassRefPtr<StringCallback> callback)
269 {
270     if (!isValid()) {
271         callback->invalidate();
272         return;
273     }
274
275     uint64_t callbackID = callback->callbackID();
276     m_stringCallbacks.set(callbackID, callback);
277     m_process->send(Messages::WebPage::ApplyAutocorrection(correction, originalText, callbackID), m_pageID);
278 }
279
280 void WebPageProxy::requestAutocorrectionContext(PassRefPtr<AutocorrectionContextCallback> callback)
281 {
282     if (!isValid()) {
283         callback->invalidate();
284         return;
285     }
286
287     uint64_t callbackID = callback->callbackID();
288     m_autocorrectionContextCallbacks.set(callbackID, callback);
289     m_process->send(Messages::WebPage::RequestAutocorrectionContext(callbackID), m_pageID);
290 }
291
292 void WebPageProxy::getAutocorrectionContext(String& beforeContext, String& markedText, String& selectedText, String& afterContext, uint64_t& location, uint64_t& length)
293 {
294     m_process->sendSync(Messages::WebPage::GetAutocorrectionContext(), Messages::WebPage::GetAutocorrectionContext::Reply(beforeContext, markedText, selectedText, afterContext, location, length), m_pageID);
295 }
296
297 void WebPageProxy::selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback> callback)
298 {
299     if (!isValid()) {
300         callback->invalidate();
301         return;
302     }
303
304     uint64_t callbackID = callback->callbackID();
305     m_gestureCallbacks.set(callbackID, callback);
306     m_process->send(Messages::WebPage::SelectWithTwoTouches(from, to, gestureType, gestureState, callbackID), m_pageID);
307 }
308
309 void WebPageProxy::didReceivePositionInformation(const InteractionInformationAtPosition& info)
310 {
311     m_pageClient.positionInformationDidChange(info);
312 }
313
314 void WebPageProxy::getPositionInformation(const WebCore::IntPoint& point, InteractionInformationAtPosition& info)
315 {
316     m_process->sendSync(Messages::WebPage::GetPositionInformation(point), Messages::WebPage::GetPositionInformation::Reply(info), m_pageID);
317 }
318
319 void WebPageProxy::requestPositionInformation(const WebCore::IntPoint& point)
320 {
321     m_process->send(Messages::WebPage::RequestPositionInformation(point), m_pageID);
322 }
323
324 void WebPageProxy::startInteractionWithElementAtPosition(const WebCore::IntPoint& point)
325 {
326     m_process->send(Messages::WebPage::StartInteractionWithElementAtPosition(point), m_pageID);
327 }
328
329 void WebPageProxy::stopInteraction()
330 {
331     m_process->send(Messages::WebPage::StopInteraction(), m_pageID);
332 }
333
334 void WebPageProxy::performActionOnElement(uint32_t action)
335 {
336     m_process->send(Messages::WebPage::PerformActionOnElement(action), m_pageID);
337 }
338
339 void WebPageProxy::saveImageToLibrary(const SharedMemory::Handle& imageHandle, uint64_t imageSize)
340 {
341     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(imageHandle, SharedMemory::ReadOnly);
342     RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), imageSize);
343     m_pageClient.saveImageToLibrary(buffer);
344 }
345
346 void WebPageProxy::notifyRevealedSelection()
347 {
348     m_pageClient.selectionDidChange();
349 }
350
351 void WebPageProxy::extendSelection(WebCore::TextGranularity granularity)
352 {
353     m_process->send(Messages::WebPage::ExtendSelection(static_cast<uint32_t>(granularity)), m_pageID);
354 }
355
356 void WebPageProxy::interpretQueuedKeyEvent(const EditorState&, bool&, Vector<WebCore::KeypressCommand>&)
357 {
358     notImplemented();
359 }
360
361 void WebPageProxy::interpretKeyEvent(const EditorState& state, bool isCharEvent, bool& handled)
362 {
363     m_editorState = state;
364     handled = m_pageClient.interpretKeyEvent(m_keyEventQueue.first(), isCharEvent);
365 }
366
367 // Complex text input support for plug-ins.
368 void WebPageProxy::sendComplexTextInputToPlugin(uint64_t, const String&)
369 {
370     notImplemented();
371 }
372
373 void WebPageProxy::setSmartInsertDeleteEnabled(bool)
374 {
375     notImplemented();
376 }
377
378 void WebPageProxy::registerWebProcessAccessibilityToken(const IPC::DataReference&)
379 {
380     notImplemented();
381 }    
382
383 void WebPageProxy::makeFirstResponder()
384 {
385     notImplemented();
386 }
387
388 void WebPageProxy::registerUIProcessAccessibilityTokens(const IPC::DataReference&, const IPC::DataReference&)
389 {
390     notImplemented();
391 }
392
393 void WebPageProxy::pluginFocusOrWindowFocusChanged(uint64_t, bool)
394 {
395     notImplemented();
396 }
397
398 void WebPageProxy::setPluginComplexTextInputState(uint64_t, uint64_t)
399 {
400     notImplemented();
401 }
402
403 void WebPageProxy::executeSavedCommandBySelector(const String&, bool&)
404 {
405     notImplemented();
406 }
407
408 bool WebPageProxy::shouldDelayWindowOrderingForEvent(const WebKit::WebMouseEvent&)
409 {
410     notImplemented();
411     return false;
412 }
413
414 bool WebPageProxy::acceptsFirstMouse(int, const WebKit::WebMouseEvent&)
415 {
416     notImplemented();
417     return false;
418 }
419
420 void WebPageProxy::didFinishScrolling(const WebCore::FloatPoint& contentOffset)
421 {
422     process().send(Messages::WebPage::DidFinishScrolling(contentOffset), m_pageID);
423 }
424
425 void WebPageProxy::didFinishZooming(float newScale)
426 {
427     m_pageScaleFactor = newScale;
428     process().send(Messages::WebPage::DidFinishZooming(newScale), m_pageID);
429 }
430
431 void WebPageProxy::tapHighlightAtPosition(const WebCore::FloatPoint& position, uint64_t& requestID)
432 {
433     static uint64_t uniqueRequestID = 0;
434     requestID = ++uniqueRequestID;
435
436     process().send(Messages::WebPage::TapHighlightAtPosition(requestID, position), m_pageID);
437 }
438
439 void WebPageProxy::blurAssistedNode()
440 {
441     process().send(Messages::WebPage::BlurAssistedNode(), m_pageID);
442 }
443
444 void WebPageProxy::mainDocumentDidReceiveMobileDocType()
445 {
446     m_pageClient.mainDocumentDidReceiveMobileDocType();
447 }
448
449 void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius)
450 {
451     m_pageClient.didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
452 }
453
454 void WebPageProxy::didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments)
455 {
456     m_pageClient.didChangeViewportArguments(viewportArguments);
457 }
458
459 void WebPageProxy::startAssistingNode(const WebCore::IntRect& scrollRect, bool hasNextFocusable, bool hasPreviousFocusable)
460 {
461     m_pageClient.startAssistingNode(scrollRect, hasNextFocusable, hasPreviousFocusable);
462 }
463
464 void WebPageProxy::stopAssistingNode()
465 {
466     m_pageClient.stopAssistingNode();
467 }
468
469 void WebPageProxy::didPerformDictionaryLookup(const AttributedString&, const DictionaryPopupInfo&)
470 {
471     notImplemented();
472 }
473
474 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String&, const String&, const IPC::DataReference&, const String&)
475 {
476     notImplemented();
477 }
478
479 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplicationRaw(const String&, const String&, const uint8_t*, unsigned long, const String&)
480 {
481     notImplemented();
482 }
483
484 void WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication(const String&)
485 {
486     notImplemented();
487 }
488
489 void WebPageProxy::setAcceleratedCompositingRootLayer(PlatformLayer* rootLayer)
490 {
491     m_pageClient.setAcceleratedCompositingRootLayer(rootLayer);
492 }
493
494 } // namespace WebKit