Remove unused ChromeClient::formStateDidChange().
[WebKit-https.git] / Source / WebKit / efl / WebCoreSupport / ChromeClientEfl.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
4  * Copyright (C) 2008 Kenneth Rohde Christiansen
5  * Copyright (C) 2008 Diego Gonzalez
6  * Copyright (C) 2009-2010 ProFUSION embedded systems
7  * Copyright (C) 2009-2012 Samsung Electronics
8  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
9  *
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "config.h"
35 #include "ChromeClientEfl.h"
36
37 #include "ApplicationCacheStorage.h"
38 #include "FileChooser.h"
39 #include "FileIconLoader.h"
40 #include "FloatRect.h"
41 #include "Frame.h"
42 #include "FrameLoader.h"
43 #include "FrameLoaderClientEfl.h"
44 #include "HitTestResult.h"
45 #include "IntRect.h"
46 #include "URL.h"
47 #include "NavigationAction.h"
48 #include "NotImplemented.h"
49 #include "PopupMenuEfl.h"
50 #include "SearchPopupMenuEfl.h"
51 #include "SecurityOrigin.h"
52 #include "ViewportArguments.h"
53 #include "WindowFeatures.h"
54 #include "ewk_custom_handler_private.h"
55 #include "ewk_file_chooser_private.h"
56 #include "ewk_frame_private.h"
57 #include "ewk_private.h"
58 #include "ewk_security_origin_private.h"
59 #include "ewk_view_private.h"
60 #include <Ecore_Evas.h>
61 #include <Evas.h>
62 #include <wtf/text/CString.h>
63 #include <wtf/text/WTFString.h>
64
65 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
66 #include "NotificationPresenterClientEfl.h"
67 #endif
68
69 #if ENABLE(SQL_DATABASE)
70 #include "DatabaseDetails.h"
71 #include "DatabaseManager.h"
72 #endif
73
74 #if ENABLE(INPUT_TYPE_COLOR)
75 #include "ColorChooserEfl.h"
76 #endif
77
78 #if ENABLE(FULLSCREEN_API)
79 #include "Settings.h"
80 #endif
81
82 using namespace WebCore;
83
84 static inline Evas_Object* kit(Frame* frame)
85 {
86     if (!frame)
87         return 0;
88
89     FrameLoaderClientEfl& client = static_cast<FrameLoaderClientEfl&>(frame->loader().client());
90     return client.webFrame();
91 }
92
93 namespace WebCore {
94
95 ChromeClientEfl::ChromeClientEfl(Evas_Object* view)
96     : m_view(view)
97 {
98     ASSERT(m_view);
99 }
100
101 ChromeClientEfl::~ChromeClientEfl()
102 {
103 }
104
105 void ChromeClientEfl::chromeDestroyed()
106 {
107     delete this;
108 }
109
110 void ChromeClientEfl::focusedElementChanged(Element*)
111 {
112     notImplemented();
113 }
114
115 void ChromeClientEfl::focusedFrameChanged(Frame*)
116 {
117 }
118
119 FloatRect ChromeClientEfl::windowRect()
120 {
121     int x, y, width, height;
122
123     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
124     ecore_evas_request_geometry_get(ee, &x, &y, &width, &height);
125
126     return FloatRect(x, y, width, height);
127 }
128
129 void ChromeClientEfl::setWindowRect(const FloatRect& rect)
130 {
131     if (!ewk_view_setting_enable_auto_resize_window_get(m_view))
132         return;
133
134     Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
135     ecore_evas_move_resize(ee, rect.x(), rect.y(), rect.width(), rect.height());
136 }
137
138 FloatRect ChromeClientEfl::pageRect()
139 {
140     return ewk_view_page_rect_get(m_view);
141 }
142
143 void ChromeClientEfl::focus()
144 {
145     evas_object_focus_set(m_view, EINA_TRUE);
146 }
147
148 void ChromeClientEfl::unfocus()
149 {
150     evas_object_focus_set(m_view, EINA_FALSE);
151 }
152
153 Page* ChromeClientEfl::createWindow(Frame* frame, const FrameLoadRequest&, const WindowFeatures& features, const NavigationAction&)
154 {
155 #if ENABLE(FULLSCREEN_API)
156     if (frame->document() && frame->document()->webkitCurrentFullScreenElement())
157         frame->document()->webkitCancelFullScreen();
158 #else
159     UNUSED_PARAM(frame);
160 #endif
161
162     Evas_Object* newView = ewk_view_window_create(m_view, EINA_TRUE, &features);
163     if (!newView)
164         return 0;
165
166     return EWKPrivate::corePage(newView);
167 }
168
169 void ChromeClientEfl::show()
170 {
171     ewk_view_ready(m_view);
172 }
173
174 bool ChromeClientEfl::canRunModal()
175 {
176     notImplemented();
177     return false;
178 }
179
180 void ChromeClientEfl::runModal()
181 {
182     notImplemented();
183 }
184
185 void ChromeClientEfl::setToolbarsVisible(bool visible)
186 {
187     ewk_view_toolbars_visible_set(m_view, visible);
188 }
189
190 bool ChromeClientEfl::toolbarsVisible()
191 {
192     bool visible;
193
194     ewk_view_toolbars_visible_get(m_view, &visible);
195     return visible;
196 }
197
198 void ChromeClientEfl::setStatusbarVisible(bool visible)
199 {
200     ewk_view_statusbar_visible_set(m_view, visible);
201 }
202
203 bool ChromeClientEfl::statusbarVisible()
204 {
205     bool visible;
206
207     ewk_view_statusbar_visible_get(m_view, &visible);
208     return visible;
209 }
210
211 void ChromeClientEfl::setScrollbarsVisible(bool visible)
212 {
213     ewk_view_scrollbars_visible_set(m_view, visible);
214 }
215
216 bool ChromeClientEfl::scrollbarsVisible()
217 {
218     bool visible;
219
220     ewk_view_scrollbars_visible_get(m_view, &visible);
221     return visible;
222 }
223
224 void ChromeClientEfl::setMenubarVisible(bool visible)
225 {
226     ewk_view_menubar_visible_set(m_view, visible);
227 }
228
229 bool ChromeClientEfl::menubarVisible()
230 {
231     bool visible;
232
233     ewk_view_menubar_visible_get(m_view, &visible);
234     return visible;
235 }
236
237 void ChromeClientEfl::createSelectPopup(PopupMenuClient* client, int selected, const IntRect& rect)
238 {
239     ewk_view_popup_new(m_view, client, selected, rect);
240 }
241
242 bool ChromeClientEfl::destroySelectPopup()
243 {
244     return ewk_view_popup_destroy(m_view);
245 }
246
247 void ChromeClientEfl::setResizable(bool)
248 {
249     notImplemented();
250 }
251
252 void ChromeClientEfl::closeWindowSoon()
253 {
254     ewk_view_window_close(m_view);
255 }
256
257 bool ChromeClientEfl::canTakeFocus(FocusDirection coreDirection)
258 {
259     // This is called when cycling through links/focusable objects and we
260     // reach the last focusable object.
261     ASSERT(coreDirection == FocusDirectionForward || coreDirection == FocusDirectionBackward);
262
263     Ewk_Focus_Direction direction = static_cast<Ewk_Focus_Direction>(coreDirection);
264
265     return !ewk_view_focus_can_cycle(m_view, direction);
266 }
267
268 void ChromeClientEfl::takeFocus(FocusDirection)
269 {
270     unfocus();
271 }
272
273 bool ChromeClientEfl::canRunBeforeUnloadConfirmPanel()
274 {
275     return true;
276 }
277
278 bool ChromeClientEfl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
279 {
280     return ewk_view_run_before_unload_confirm(m_view, kit(frame), message.utf8().data());
281 }
282
283 void ChromeClientEfl::addMessageToConsole(MessageSource, MessageLevel, const String& message,
284                                           unsigned lineNumber, unsigned columnNumber, const String& sourceID)
285 {
286     UNUSED_PARAM(columnNumber);
287     ewk_view_add_console_message(m_view, message.utf8().data(), lineNumber, sourceID.utf8().data());
288 }
289
290 void ChromeClientEfl::runJavaScriptAlert(Frame* frame, const String& message)
291 {
292     ewk_view_run_javascript_alert(m_view, kit(frame), message.utf8().data());
293 }
294
295 bool ChromeClientEfl::runJavaScriptConfirm(Frame* frame, const String& message)
296 {
297     return ewk_view_run_javascript_confirm(m_view, kit(frame), message.utf8().data());
298 }
299
300 bool ChromeClientEfl::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
301 {
302     const char* value = 0;
303     ewk_view_run_javascript_prompt(m_view, kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value);
304     if (value) {
305         result = String::fromUTF8(value);
306         eina_stringshare_del(value);
307         return true;
308     }
309     return false;
310 }
311
312 void ChromeClientEfl::setStatusbarText(const String& string)
313 {
314     ewk_view_statusbar_text_set(m_view, string.utf8().data());
315 }
316
317 bool ChromeClientEfl::shouldInterruptJavaScript()
318 {
319     return ewk_view_should_interrupt_javascript(m_view);
320 }
321
322 KeyboardUIMode ChromeClientEfl::keyboardUIMode()
323 {
324     return ewk_view_setting_include_links_in_focus_chain_get(m_view) ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
325 }
326
327 IntRect ChromeClientEfl::windowResizerRect() const
328 {
329     notImplemented();
330     // Implementing this function will make repaint being
331     // called during resize, but as this will be done with
332     // a minor delay it adds a weird "filling" effect due
333     // to us using an evas image for showing the cairo
334     // context. So instead of implementing this function
335     // we call paint directly during resize with
336     // the new object size as its argument.
337     return IntRect();
338 }
339
340 void ChromeClientEfl::contentsSizeChanged(Frame* frame, const IntSize& size) const
341 {
342     ewk_frame_contents_size_changed(kit(frame), size.width(), size.height());
343     if (ewk_view_frame_main_get(m_view) == kit(frame))
344         ewk_view_contents_size_changed(m_view, size.width(), size.height());
345 }
346
347 IntRect ChromeClientEfl::rootViewToScreen(const IntRect& rect) const
348 {
349     notImplemented();
350     return rect;
351 }
352
353 IntPoint ChromeClientEfl::screenToRootView(const IntPoint& point) const
354 {
355     notImplemented();
356     return point;
357 }
358
359 PlatformPageClient ChromeClientEfl::platformPageClient() const
360 {
361     return EWKPrivate::corePageClient(m_view);
362 }
363
364 void ChromeClientEfl::scrollbarsModeDidChange() const
365 {
366 }
367
368 void ChromeClientEfl::mouseDidMoveOverElement(const HitTestResult& hit, unsigned /*modifierFlags*/)
369 {
370     // FIXME, compare with old link, look at Qt impl.
371     bool isLink = hit.isLiveLink();
372     if (isLink) {
373         URL url = hit.absoluteLinkURL();
374         if (!url.isEmpty() && url != m_hoveredLinkURL) {
375             const char* link[2];
376             TextDirection dir;
377             CString urlStr = url.string().utf8();
378             CString titleStr = hit.title(dir).utf8();
379             link[0] = urlStr.data();
380             link[1] = titleStr.data();
381             ewk_view_mouse_link_hover_in(m_view, link);
382             m_hoveredLinkURL = url;
383         }
384     } else if (!isLink && !m_hoveredLinkURL.isEmpty()) {
385         ewk_view_mouse_link_hover_out(m_view);
386         m_hoveredLinkURL = URL();
387     }
388 }
389
390 void ChromeClientEfl::setToolTip(const String& toolTip, TextDirection)
391 {
392     ewk_view_tooltip_text_set(m_view, toolTip.utf8().data());
393 }
394
395 void ChromeClientEfl::print(Frame*)
396 {
397     notImplemented();
398 }
399
400 void ChromeClientEfl::reachedMaxAppCacheSize(int64_t /*spaceNeeded*/)
401 {
402     // FIXME: Free some space.
403     notImplemented();
404 }
405
406 void ChromeClientEfl::reachedApplicationCacheOriginQuota(SecurityOrigin* origin, int64_t totalSpaceNeeded)
407 {
408     Ewk_Security_Origin* ewkOrigin = ewk_security_origin_new(origin);
409     int64_t defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
410
411     int64_t newQuota = ewk_view_exceeded_application_cache_quota(m_view, ewkOrigin, defaultOriginQuota, totalSpaceNeeded);
412     if (newQuota)
413         ewk_security_origin_application_cache_quota_set(ewkOrigin, newQuota);
414
415     ewk_security_origin_free(ewkOrigin);
416 }
417
418 void ChromeClientEfl::populateVisitedLinks()
419 {
420     evas_object_smart_callback_call(m_view, "populate,visited,links", 0);
421 }
422
423 #if ENABLE(TOUCH_EVENTS)
424 void ChromeClientEfl::needTouchEvents(bool needed)
425 {
426     ewk_view_need_touch_events_set(m_view, needed);
427 }
428 #endif
429
430 #if ENABLE(SQL_DATABASE)
431 void ChromeClientEfl::exceededDatabaseQuota(Frame* frame, const String& databaseName, DatabaseDetails details)
432 {
433     uint64_t quota;
434     SecurityOrigin* origin = frame->document()->securityOrigin();
435
436     quota = ewk_view_exceeded_database_quota(m_view,
437                                              kit(frame), databaseName.utf8().data(),
438                                              details.currentUsage(), details.expectedUsage());
439
440     /* if client did not set quota, and database is being created now, the
441      * default quota is applied
442      */
443     if (!quota && !DatabaseManager::manager().hasEntryForOrigin(origin))
444         quota = ewk_settings_web_database_default_quota_get();
445
446     DatabaseManager::manager().setQuota(origin, quota);
447 }
448 #endif
449
450 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
451 NotificationClient* ChromeClientEfl::notificationPresenter() const
452 {
453     notImplemented();
454     return 0;
455 }
456 #endif
457
458 #if ENABLE(INPUT_TYPE_COLOR)
459 PassOwnPtr<ColorChooser> ChromeClientEfl::createColorChooser(ColorChooserClient* colorChooserClient, const Color& initialColor)
460 {
461     ewk_view_color_chooser_new(m_view, colorChooserClient, initialColor);
462
463     return adoptPtr(new ColorChooserEfl(this));
464 }
465
466 void ChromeClientEfl::removeColorChooser()
467 {
468     ewk_view_color_chooser_destroy(m_view);
469 }
470
471 void ChromeClientEfl::updateColorChooser(const Color& color)
472 {
473     ewk_view_color_chooser_changed(m_view, color);
474 }
475 #endif
476
477 void ChromeClientEfl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
478 {
479     RefPtr<FileChooser> chooser = prpFileChooser;
480     Eina_List* selectedFilenames = 0;
481     Ewk_File_Chooser* fileChooser = ewk_file_chooser_new(chooser.get());
482     bool confirm = ewk_view_run_open_panel(m_view, kit(frame), fileChooser, &selectedFilenames);
483     ewk_file_chooser_free(fileChooser);
484     if (!confirm)
485         return;
486
487     void* filename;
488     Vector<String> filenames;
489     EINA_LIST_FREE(selectedFilenames, filename) {
490         filenames.append(String::fromUTF8(static_cast<char*>(filename)));
491         free(filename);
492     }
493
494     if (chooser->settings().allowsMultipleFiles)
495         chooser->chooseFiles(filenames);
496     else
497         chooser->chooseFile(filenames[0]);
498 }
499
500 void ChromeClientEfl::setCursor(const Cursor& cursor)
501 {
502     ewk_view_cursor_set(m_view, cursor);
503 }
504
505 void ChromeClientEfl::setCursorHiddenUntilMouseMoves(bool)
506 {
507     notImplemented();
508 }
509
510 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
511 void ChromeClientEfl::scheduleAnimation()
512 {
513     notImplemented();
514 }
515
516 void ChromeClientEfl::serviceScriptedAnimations()
517 {
518     notImplemented();
519 }
520 #endif
521
522 void ChromeClientEfl::cancelGeolocationPermissionForFrame(Frame*, Geolocation*)
523 {
524     notImplemented();
525 }
526
527 void ChromeClientEfl::invalidateContents(const IntRect& /*updateRect*/, bool /*immediate*/)
528 {
529     notImplemented();
530 }
531
532 void ChromeClientEfl::invalidateRootView(const IntRect& updateRect, bool /*immediate*/)
533 {
534 #if USE(TILED_BACKING_STORE)
535     ewk_view_tiled_backing_store_invalidate(m_view, updateRect);
536 #else
537     UNUSED_PARAM(updateRect);
538     notImplemented();
539 #endif
540 }
541
542 void ChromeClientEfl::invalidateContentsAndRootView(const IntRect& updateRect, bool /*immediate*/)
543 {
544     if (updateRect.isEmpty())
545         return;
546
547     Evas_Coord x, y, w, h;
548
549     x = updateRect.x();
550     y = updateRect.y();
551     w = updateRect.width();
552     h = updateRect.height();
553     ewk_view_repaint(m_view, x, y, w, h);
554 }
555
556 void ChromeClientEfl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
557 {
558     invalidateContentsAndRootView(updateRect, immediate);
559 }
560
561 void ChromeClientEfl::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
562 {
563     ewk_view_scroll(m_view, scrollDelta, rectToScroll, clipRect);
564 }
565
566 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*)
567 {
568     notImplemented();
569 }
570
571 void ChromeClientEfl::iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>)
572 {
573     notImplemented();
574 }
575
576 void ChromeClientEfl::loadIconForFiles(const Vector<String>&, FileIconLoader*)
577 {
578     notImplemented();
579 }
580
581 void ChromeClientEfl::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
582 {
583     ewk_view_viewport_attributes_set(m_view, arguments);
584 }
585
586 bool ChromeClientEfl::selectItemWritingDirectionIsNatural()
587 {
588     return true;
589 }
590
591 bool ChromeClientEfl::selectItemAlignmentFollowsMenuWritingDirection()
592 {
593     return false;
594 }
595
596 bool ChromeClientEfl::hasOpenedPopup() const
597 {
598     notImplemented();
599     return false;
600 }
601
602 PassRefPtr<PopupMenu> ChromeClientEfl::createPopupMenu(PopupMenuClient* client) const
603 {
604     return adoptRef(new PopupMenuEfl(client));
605 }
606
607 PassRefPtr<SearchPopupMenu> ChromeClientEfl::createSearchPopupMenu(PopupMenuClient* client) const
608 {
609     return adoptRef(new SearchPopupMenuEfl(client));
610 }
611
612 void ChromeClientEfl::attachRootGraphicsLayer(Frame*, GraphicsLayer* rootLayer)
613 {
614     ewk_view_root_graphics_layer_set(m_view, rootLayer);
615 }
616
617 void ChromeClientEfl::setNeedsOneShotDrawingSynchronization()
618 {
619     ewk_view_mark_for_sync(m_view);
620 }
621
622 void ChromeClientEfl::scheduleCompositingLayerFlush()
623 {
624     ewk_view_mark_for_sync(m_view);
625 }
626
627 ChromeClient::CompositingTriggerFlags ChromeClientEfl::allowedCompositingTriggers() const
628 {
629     return AllTriggers;
630 }
631
632 #if ENABLE(FULLSCREEN_API)
633 bool ChromeClientEfl::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
634 {
635     UNUSED_PARAM(withKeyboard);
636
637     if (!element->document().page())
638         return false;
639     return element->document().page()->settings().fullScreenEnabled();
640 }
641
642 void ChromeClientEfl::enterFullScreenForElement(WebCore::Element* element)
643 {
644     // Keep a reference to the element to use it later in
645     // exitFullScreenForElement().
646     m_fullScreenElement = element;
647
648     element->document().webkitWillEnterFullScreenForElement(element);
649     ewk_view_fullscreen_enter(m_view);
650     element->document().webkitDidEnterFullScreenForElement(element);
651 }
652
653 void ChromeClientEfl::exitFullScreenForElement(WebCore::Element*)
654 {
655     // The element passed into this function is not reliable, i.e. it could
656     // be null. In addition the parameter may be disappearing in the future.
657     // So we use the reference to the element we saved above.
658     ASSERT(m_fullScreenElement);
659
660     m_fullScreenElement->document().webkitWillExitFullScreenForElement(m_fullScreenElement.get());
661     ewk_view_fullscreen_exit(m_view);
662     m_fullScreenElement->document().webkitDidExitFullScreenForElement(m_fullScreenElement.get());
663
664     m_fullScreenElement.clear();
665 }
666 #endif
667
668 #if USE(TILED_BACKING_STORE)
669 void ChromeClientEfl::delegatedScrollRequested(const IntPoint&)
670 {
671     notImplemented();
672 }
673
674 IntRect ChromeClientEfl::visibleRectForTiledBackingStore() const
675 {
676     WebCore::FloatRect rect = ewk_view_page_rect_get(m_view);
677     const Evas_Object* frame = ewk_view_frame_main_get(m_view);
678
679     int x, y;
680     ewk_frame_scroll_pos_get(frame, &x, &y);
681     return IntRect(x, y, rect.width(), rect.height());
682 }
683 #endif
684
685 }