• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2010 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  #if ENABLE(DATABASE)
38  #include "DatabaseDetails.h"
39  #include "DatabaseTracker.h"
40  #endif
41  #include "EWebKit.h"
42  #include "FileChooser.h"
43  #include "FloatRect.h"
44  #include "FrameLoader.h"
45  #include "FrameLoaderClientEfl.h"
46  #include "HitTestResult.h"
47  #include "IntRect.h"
48  #include "KURL.h"
49  #include "NavigationAction.h"
50  #include "NotImplemented.h"
51  #include "PlatformString.h"
52  #include "SecurityOrigin.h"
53  #include "PopupMenuEfl.h"
54  #include "SearchPopupMenuEfl.h"
55  #include "ViewportArguments.h"
56  #include "WindowFeatures.h"
57  #include "ewk_private.h"
58  #include <Ecore_Evas.h>
59  #include <Evas.h>
60  #include <wtf/text/CString.h>
61  
62  using namespace WebCore;
63  
kit(Frame * frame)64  static inline Evas_Object* kit(Frame* frame)
65  {
66      if (!frame)
67          return 0;
68  
69      FrameLoaderClientEfl* client = static_cast<FrameLoaderClientEfl*>(frame->loader()->client());
70      return client ? client->webFrame() : 0;
71  }
72  
73  namespace WebCore {
74  
ChromeClientEfl(Evas_Object * view)75  ChromeClientEfl::ChromeClientEfl(Evas_Object* view)
76      : m_view(view)
77  {
78  }
79  
~ChromeClientEfl()80  ChromeClientEfl::~ChromeClientEfl()
81  {
82  }
83  
chromeDestroyed()84  void ChromeClientEfl::chromeDestroyed()
85  {
86      delete this;
87  }
88  
focusedNodeChanged(Node *)89  void ChromeClientEfl::focusedNodeChanged(Node*)
90  {
91      notImplemented();
92  }
93  
focusedFrameChanged(Frame *)94  void ChromeClientEfl::focusedFrameChanged(Frame*)
95  {
96  }
97  
windowRect()98  FloatRect ChromeClientEfl::windowRect()
99  {
100      Ecore_Evas* ee = 0;
101      int x, y, w, h;
102  
103      if (!m_view)
104          return FloatRect();
105  
106      ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
107      ecore_evas_geometry_get(ee, &x, &y, &w, &h);
108      return FloatRect(x, y, w, h);
109  }
110  
setWindowRect(const FloatRect & rect)111  void ChromeClientEfl::setWindowRect(const FloatRect& rect)
112  {
113      Ecore_Evas* ee = 0;
114      IntRect intrect = IntRect(rect);
115  
116      if (!m_view)
117          return;
118  
119      if (!ewk_view_setting_enable_auto_resize_window_get(m_view))
120          return;
121  
122      ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view));
123      ecore_evas_move(ee, intrect.x(), intrect.y());
124      ecore_evas_resize(ee, intrect.width(), intrect.height());
125  }
126  
pageRect()127  FloatRect ChromeClientEfl::pageRect()
128  {
129      if (!m_view)
130          return FloatRect();
131  
132      return ewk_view_page_rect_get(m_view);
133  }
134  
scaleFactor()135  float ChromeClientEfl::scaleFactor()
136  {
137      notImplemented();
138      return 1.0;
139  }
140  
focus()141  void ChromeClientEfl::focus()
142  {
143      evas_object_focus_set(m_view, EINA_TRUE);
144  }
145  
unfocus()146  void ChromeClientEfl::unfocus()
147  {
148      evas_object_focus_set(m_view, EINA_FALSE);
149  }
150  
createWindow(Frame *,const FrameLoadRequest & frameLoadRequest,const WindowFeatures & features,const NavigationAction &)151  Page* ChromeClientEfl::createWindow(Frame*, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& features, const NavigationAction&)
152  {
153      Evas_Object* newView = ewk_view_window_create(m_view, EINA_TRUE, &features);
154      if (!newView)
155          return 0;
156  
157      return ewk_view_core_page_get(newView);
158  }
159  
show()160  void ChromeClientEfl::show()
161  {
162      ewk_view_ready(m_view);
163  }
164  
canRunModal()165  bool ChromeClientEfl::canRunModal()
166  {
167      notImplemented();
168      return false;
169  }
170  
runModal()171  void ChromeClientEfl::runModal()
172  {
173      notImplemented();
174  }
175  
setToolbarsVisible(bool visible)176  void ChromeClientEfl::setToolbarsVisible(bool visible)
177  {
178      ewk_view_toolbars_visible_set(m_view, visible);
179  }
180  
toolbarsVisible()181  bool ChromeClientEfl::toolbarsVisible()
182  {
183      Eina_Bool visible;
184  
185      ewk_view_toolbars_visible_get(m_view, &visible);
186      return visible;
187  }
188  
setStatusbarVisible(bool visible)189  void ChromeClientEfl::setStatusbarVisible(bool visible)
190  {
191      ewk_view_statusbar_visible_set(m_view, visible);
192  }
193  
statusbarVisible()194  bool ChromeClientEfl::statusbarVisible()
195  {
196      Eina_Bool visible;
197  
198      ewk_view_statusbar_visible_get(m_view, &visible);
199      return visible;
200  }
201  
setScrollbarsVisible(bool visible)202  void ChromeClientEfl::setScrollbarsVisible(bool visible)
203  {
204      ewk_view_scrollbars_visible_set(m_view, visible);
205  }
206  
scrollbarsVisible()207  bool ChromeClientEfl::scrollbarsVisible()
208  {
209      Eina_Bool visible;
210  
211      ewk_view_scrollbars_visible_get(m_view, &visible);
212      return visible;
213  }
214  
setMenubarVisible(bool visible)215  void ChromeClientEfl::setMenubarVisible(bool visible)
216  {
217      ewk_view_menubar_visible_set(m_view, visible);
218  }
219  
menubarVisible()220  bool ChromeClientEfl::menubarVisible()
221  {
222      Eina_Bool visible;
223  
224      ewk_view_menubar_visible_get(m_view, &visible);
225      return visible;
226  }
227  
createSelectPopup(PopupMenuClient * client,int selected,const IntRect & rect)228  void ChromeClientEfl::createSelectPopup(PopupMenuClient* client, int selected, const IntRect& rect)
229  {
230      ewk_view_popup_new(m_view, client, selected, rect);
231  }
232  
destroySelectPopup()233  bool ChromeClientEfl::destroySelectPopup()
234  {
235      return ewk_view_popup_destroy(m_view);
236  }
237  
setResizable(bool)238  void ChromeClientEfl::setResizable(bool)
239  {
240      notImplemented();
241  }
242  
closeWindowSoon()243  void ChromeClientEfl::closeWindowSoon()
244  {
245      ewk_view_window_close(m_view);
246  }
247  
canTakeFocus(FocusDirection)248  bool ChromeClientEfl::canTakeFocus(FocusDirection)
249  {
250      // This is called when cycling through links/focusable objects and we
251      // reach the last focusable object.
252      return false;
253  }
254  
takeFocus(FocusDirection)255  void ChromeClientEfl::takeFocus(FocusDirection)
256  {
257      unfocus();
258  }
259  
canRunBeforeUnloadConfirmPanel()260  bool ChromeClientEfl::canRunBeforeUnloadConfirmPanel()
261  {
262      return true;
263  }
264  
runBeforeUnloadConfirmPanel(const String & message,Frame * frame)265  bool ChromeClientEfl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
266  {
267      return runJavaScriptConfirm(frame, message);
268  }
269  
addMessageToConsole(MessageSource,MessageType,MessageLevel,const String & message,unsigned int lineNumber,const String & sourceID)270  void ChromeClientEfl::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
271                                            unsigned int lineNumber, const String& sourceID)
272  {
273      ewk_view_add_console_message(m_view, message.utf8().data(), lineNumber, sourceID.utf8().data());
274  }
275  
runJavaScriptAlert(Frame * frame,const String & message)276  void ChromeClientEfl::runJavaScriptAlert(Frame* frame, const String& message)
277  {
278      ewk_view_run_javascript_alert(m_view, kit(frame), message.utf8().data());
279  }
280  
runJavaScriptConfirm(Frame * frame,const String & message)281  bool ChromeClientEfl::runJavaScriptConfirm(Frame* frame, const String& message)
282  {
283      return ewk_view_run_javascript_confirm(m_view, kit(frame), message.utf8().data());
284  }
285  
runJavaScriptPrompt(Frame * frame,const String & message,const String & defaultValue,String & result)286  bool ChromeClientEfl::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
287  {
288      char* value = 0;
289      ewk_view_run_javascript_prompt(m_view, kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value);
290      if (value) {
291          result = String::fromUTF8(value);
292          free(value);
293          return true;
294      }
295      return false;
296  }
297  
setStatusbarText(const String & string)298  void ChromeClientEfl::setStatusbarText(const String& string)
299  {
300      ewk_view_statusbar_text_set(m_view, string.utf8().data());
301  }
302  
shouldInterruptJavaScript()303  bool ChromeClientEfl::shouldInterruptJavaScript()
304  {
305      return ewk_view_should_interrupt_javascript(m_view);
306  }
307  
keyboardUIMode()308  KeyboardUIMode ChromeClientEfl::keyboardUIMode()
309  {
310      return KeyboardAccessTabsToLinks;
311  }
312  
windowResizerRect() const313  IntRect ChromeClientEfl::windowResizerRect() const
314  {
315      notImplemented();
316      // Implementing this function will make repaint being
317      // called during resize, but as this will be done with
318      // a minor delay it adds a weird "filling" effect due
319      // to us using an evas image for showing the cairo
320      // context. So instead of implementing this function
321      // we call paint directly during resize with
322      // the new object size as its argument.
323      return IntRect();
324  }
325  
contentsSizeChanged(Frame * frame,const IntSize & size) const326  void ChromeClientEfl::contentsSizeChanged(Frame* frame, const IntSize& size) const
327  {
328      ewk_frame_contents_size_changed(kit(frame), size.width(), size.height());
329      if (ewk_view_frame_main_get(m_view) == kit(frame))
330          ewk_view_contents_size_changed(m_view, size.width(), size.height());
331  }
332  
windowToScreen(const IntRect & rect) const333  IntRect ChromeClientEfl::windowToScreen(const IntRect& rect) const
334  {
335      notImplemented();
336      return rect;
337  }
338  
screenToWindow(const IntPoint & point) const339  IntPoint ChromeClientEfl::screenToWindow(const IntPoint& point) const
340  {
341      notImplemented();
342      return point;
343  }
344  
platformPageClient() const345  PlatformPageClient ChromeClientEfl::platformPageClient() const
346  {
347      return m_view;
348  }
349  
scrollbarsModeDidChange() const350  void ChromeClientEfl::scrollbarsModeDidChange() const
351  {
352  }
353  
mouseDidMoveOverElement(const HitTestResult & hit,unsigned modifierFlags)354  void ChromeClientEfl::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags)
355  {
356      // FIXME, compare with old link, look at Qt impl.
357      bool isLink = hit.isLiveLink();
358      if (isLink) {
359          KURL url = hit.absoluteLinkURL();
360          if (!url.isEmpty() && url != m_hoveredLinkURL) {
361              const char* link[2];
362              TextDirection dir;
363              CString urlStr = url.string().utf8();
364              CString titleStr = hit.title(dir).utf8();
365              link[0] = urlStr.data();
366              link[1] = titleStr.data();
367              ewk_view_mouse_link_hover_in(m_view, link);
368              m_hoveredLinkURL = url;
369          }
370      } else if (!isLink && !m_hoveredLinkURL.isEmpty()) {
371          ewk_view_mouse_link_hover_out(m_view);
372          m_hoveredLinkURL = KURL();
373      }
374  }
375  
setToolTip(const String & toolTip,TextDirection)376  void ChromeClientEfl::setToolTip(const String& toolTip, TextDirection)
377  {
378      ewk_view_tooltip_text_set(m_view, toolTip.utf8().data());
379  }
380  
print(Frame * frame)381  void ChromeClientEfl::print(Frame* frame)
382  {
383      notImplemented();
384  }
385  
386  #if ENABLE(OFFLINE_WEB_APPLICATIONS)
reachedMaxAppCacheSize(int64_t spaceNeeded)387  void ChromeClientEfl::reachedMaxAppCacheSize(int64_t spaceNeeded)
388  {
389      // FIXME: Free some space.
390      notImplemented();
391  }
392  
reachedApplicationCacheOriginQuota(SecurityOrigin *)393  void ChromeClientEfl::reachedApplicationCacheOriginQuota(SecurityOrigin*)
394  {
395      notImplemented();
396  }
397  #endif
398  
399  #if ENABLE(TOUCH_EVENTS)
needTouchEvents(bool needed)400  void ChromeClientEfl::needTouchEvents(bool needed)
401  {
402      ewk_view_need_touch_events_set(m_view, needed);
403  }
404  #endif
405  
406  #if ENABLE(DATABASE)
exceededDatabaseQuota(Frame * frame,const String & databaseName)407  void ChromeClientEfl::exceededDatabaseQuota(Frame* frame, const String& databaseName)
408  {
409      uint64_t quota;
410      SecurityOrigin* origin = frame->document()->securityOrigin();
411  
412      DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, origin);
413      quota = ewk_view_exceeded_database_quota(m_view,
414              kit(frame), databaseName.utf8().data(),
415              details.currentUsage(), details.expectedUsage());
416  
417      /* if client did not set quota, and database is being created now, the
418       * default quota is applied
419       */
420      if (!quota && !DatabaseTracker::tracker().hasEntryForOrigin(origin))
421          quota = ewk_settings_web_database_default_quota_get();
422  
423      DatabaseTracker::tracker().setQuota(origin, quota);
424  }
425  #endif
426  
runOpenPanel(Frame * frame,PassRefPtr<FileChooser> prpFileChooser)427  void ChromeClientEfl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
428  {
429      RefPtr<FileChooser> chooser = prpFileChooser;
430      bool confirm;
431      Eina_List* selectedFilenames = 0;
432      Eina_List* suggestedFilenames = 0;
433      void* filename;
434      Vector<String> filenames;
435  
436      for (unsigned i = 0; i < chooser->filenames().size(); i++) {
437          CString str = chooser->filenames()[i].utf8();
438          filename = strdup(str.data());
439          suggestedFilenames = eina_list_append(suggestedFilenames, filename);
440      }
441  
442      confirm = ewk_view_run_open_panel(m_view, kit(frame), chooser->allowsMultipleFiles(), suggestedFilenames, &selectedFilenames);
443      EINA_LIST_FREE(suggestedFilenames, filename)
444          free(filename);
445  
446      if (!confirm)
447          return;
448  
449      EINA_LIST_FREE(selectedFilenames, filename) {
450          filenames.append((char *)filename);
451          free(filename);
452      }
453  
454      if (chooser->allowsMultipleFiles())
455          chooser->chooseFiles(filenames);
456      else
457          chooser->chooseFile(filenames[0]);
458  }
459  
formStateDidChange(const Node *)460  void ChromeClientEfl::formStateDidChange(const Node*)
461  {
462      notImplemented();
463  }
464  
setCursor(const Cursor &)465  void ChromeClientEfl::setCursor(const Cursor&)
466  {
467      notImplemented();
468  }
469  
requestGeolocationPermissionForFrame(Frame *,Geolocation *)470  void ChromeClientEfl::requestGeolocationPermissionForFrame(Frame*, Geolocation*)
471  {
472      // See the comment in WebCore/page/ChromeClient.h
473      notImplemented();
474  }
475  
cancelGeolocationPermissionRequestForFrame(Frame *,Geolocation *)476  void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*)
477  {
478      notImplemented();
479  }
480  
cancelGeolocationPermissionForFrame(Frame *,Geolocation *)481  void ChromeClientEfl::cancelGeolocationPermissionForFrame(Frame*, Geolocation*)
482  {
483      notImplemented();
484  }
485  
invalidateContents(const IntRect & updateRect,bool immediate)486  void ChromeClientEfl::invalidateContents(const IntRect& updateRect, bool immediate)
487  {
488      notImplemented();
489  }
490  
invalidateWindow(const IntRect & updateRect,bool immediate)491  void ChromeClientEfl::invalidateWindow(const IntRect& updateRect, bool immediate)
492  {
493      notImplemented();
494  }
495  
invalidateContentsAndWindow(const IntRect & updateRect,bool immediate)496  void ChromeClientEfl::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate)
497  {
498      Evas_Coord x, y, w, h;
499  
500      x = updateRect.x();
501      y = updateRect.y();
502      w = updateRect.width();
503      h = updateRect.height();
504      ewk_view_repaint(m_view, x, y, w, h);
505  }
506  
invalidateContentsForSlowScroll(const IntRect & updateRect,bool immediate)507  void ChromeClientEfl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
508  {
509      invalidateContentsAndWindow(updateRect, immediate);
510  }
511  
scroll(const IntSize & scrollDelta,const IntRect & rectToScroll,const IntRect & clipRect)512  void ChromeClientEfl::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
513  {
514      ewk_view_scroll(m_view, scrollDelta.width(), scrollDelta.height(), rectToScroll.x(), rectToScroll.y(), rectToScroll.width(), rectToScroll.height(), clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height(), EINA_TRUE);
515  }
516  
cancelGeolocationPermissionRequestForFrame(Frame *)517  void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*)
518  {
519      notImplemented();
520  }
521  
iconForFiles(const Vector<String,0u> &,PassRefPtr<FileChooser>)522  void ChromeClientEfl::iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>)
523  {
524      notImplemented();
525  }
526  
chooseIconForFiles(const Vector<String> &,FileChooser *)527  void ChromeClientEfl::chooseIconForFiles(const Vector<String>&, FileChooser*)
528  {
529      notImplemented();
530  }
531  
dispatchViewportDataDidChange(const ViewportArguments & arguments) const532  void ChromeClientEfl::dispatchViewportDataDidChange(const ViewportArguments& arguments) const
533  {
534      ewk_view_viewport_attributes_set(m_view, arguments);
535  }
536  
selectItemWritingDirectionIsNatural()537  bool ChromeClientEfl::selectItemWritingDirectionIsNatural()
538  {
539      return true;
540  }
541  
selectItemAlignmentFollowsMenuWritingDirection()542  bool ChromeClientEfl::selectItemAlignmentFollowsMenuWritingDirection()
543  {
544      return false;
545  }
546  
createPopupMenu(PopupMenuClient * client) const547  PassRefPtr<PopupMenu> ChromeClientEfl::createPopupMenu(PopupMenuClient* client) const
548  {
549      return adoptRef(new PopupMenuEfl(client));
550  }
551  
createSearchPopupMenu(PopupMenuClient * client) const552  PassRefPtr<SearchPopupMenu> ChromeClientEfl::createSearchPopupMenu(PopupMenuClient* client) const
553  {
554      return adoptRef(new SearchPopupMenuEfl(client));
555  }
556  
557  }
558