Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2006 Zack Rusin <zack (at) 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 
     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 
     75 ChromeClientEfl::ChromeClientEfl(Evas_Object* view)
     76     : m_view(view)
     77 {
     78 }
     79 
     80 ChromeClientEfl::~ChromeClientEfl()
     81 {
     82 }
     83 
     84 void ChromeClientEfl::chromeDestroyed()
     85 {
     86     delete this;
     87 }
     88 
     89 void ChromeClientEfl::focusedNodeChanged(Node*)
     90 {
     91     notImplemented();
     92 }
     93 
     94 void ChromeClientEfl::focusedFrameChanged(Frame*)
     95 {
     96 }
     97 
     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 
    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 
    127 FloatRect ChromeClientEfl::pageRect()
    128 {
    129     if (!m_view)
    130         return FloatRect();
    131 
    132     return ewk_view_page_rect_get(m_view);
    133 }
    134 
    135 float ChromeClientEfl::scaleFactor()
    136 {
    137     notImplemented();
    138     return 1.0;
    139 }
    140 
    141 void ChromeClientEfl::focus()
    142 {
    143     evas_object_focus_set(m_view, EINA_TRUE);
    144 }
    145 
    146 void ChromeClientEfl::unfocus()
    147 {
    148     evas_object_focus_set(m_view, EINA_FALSE);
    149 }
    150 
    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 
    160 void ChromeClientEfl::show()
    161 {
    162     ewk_view_ready(m_view);
    163 }
    164 
    165 bool ChromeClientEfl::canRunModal()
    166 {
    167     notImplemented();
    168     return false;
    169 }
    170 
    171 void ChromeClientEfl::runModal()
    172 {
    173     notImplemented();
    174 }
    175 
    176 void ChromeClientEfl::setToolbarsVisible(bool visible)
    177 {
    178     ewk_view_toolbars_visible_set(m_view, visible);
    179 }
    180 
    181 bool ChromeClientEfl::toolbarsVisible()
    182 {
    183     Eina_Bool visible;
    184 
    185     ewk_view_toolbars_visible_get(m_view, &visible);
    186     return visible;
    187 }
    188 
    189 void ChromeClientEfl::setStatusbarVisible(bool visible)
    190 {
    191     ewk_view_statusbar_visible_set(m_view, visible);
    192 }
    193 
    194 bool ChromeClientEfl::statusbarVisible()
    195 {
    196     Eina_Bool visible;
    197 
    198     ewk_view_statusbar_visible_get(m_view, &visible);
    199     return visible;
    200 }
    201 
    202 void ChromeClientEfl::setScrollbarsVisible(bool visible)
    203 {
    204     ewk_view_scrollbars_visible_set(m_view, visible);
    205 }
    206 
    207 bool ChromeClientEfl::scrollbarsVisible()
    208 {
    209     Eina_Bool visible;
    210 
    211     ewk_view_scrollbars_visible_get(m_view, &visible);
    212     return visible;
    213 }
    214 
    215 void ChromeClientEfl::setMenubarVisible(bool visible)
    216 {
    217     ewk_view_menubar_visible_set(m_view, visible);
    218 }
    219 
    220 bool ChromeClientEfl::menubarVisible()
    221 {
    222     Eina_Bool visible;
    223 
    224     ewk_view_menubar_visible_get(m_view, &visible);
    225     return visible;
    226 }
    227 
    228 void ChromeClientEfl::createSelectPopup(PopupMenuClient* client, int selected, const IntRect& rect)
    229 {
    230     ewk_view_popup_new(m_view, client, selected, rect);
    231 }
    232 
    233 bool ChromeClientEfl::destroySelectPopup()
    234 {
    235     return ewk_view_popup_destroy(m_view);
    236 }
    237 
    238 void ChromeClientEfl::setResizable(bool)
    239 {
    240     notImplemented();
    241 }
    242 
    243 void ChromeClientEfl::closeWindowSoon()
    244 {
    245     ewk_view_window_close(m_view);
    246 }
    247 
    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 
    255 void ChromeClientEfl::takeFocus(FocusDirection)
    256 {
    257     unfocus();
    258 }
    259 
    260 bool ChromeClientEfl::canRunBeforeUnloadConfirmPanel()
    261 {
    262     return true;
    263 }
    264 
    265 bool ChromeClientEfl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
    266 {
    267     return runJavaScriptConfirm(frame, message);
    268 }
    269 
    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 
    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 
    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 
    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 
    298 void ChromeClientEfl::setStatusbarText(const String& string)
    299 {
    300     ewk_view_statusbar_text_set(m_view, string.utf8().data());
    301 }
    302 
    303 bool ChromeClientEfl::shouldInterruptJavaScript()
    304 {
    305     return ewk_view_should_interrupt_javascript(m_view);
    306 }
    307 
    308 KeyboardUIMode ChromeClientEfl::keyboardUIMode()
    309 {
    310     return KeyboardAccessTabsToLinks;
    311 }
    312 
    313 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 
    326 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 
    333 IntRect ChromeClientEfl::windowToScreen(const IntRect& rect) const
    334 {
    335     notImplemented();
    336     return rect;
    337 }
    338 
    339 IntPoint ChromeClientEfl::screenToWindow(const IntPoint& point) const
    340 {
    341     notImplemented();
    342     return point;
    343 }
    344 
    345 PlatformPageClient ChromeClientEfl::platformPageClient() const
    346 {
    347     return m_view;
    348 }
    349 
    350 void ChromeClientEfl::scrollbarsModeDidChange() const
    351 {
    352 }
    353 
    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 
    376 void ChromeClientEfl::setToolTip(const String& toolTip, TextDirection)
    377 {
    378     ewk_view_tooltip_text_set(m_view, toolTip.utf8().data());
    379 }
    380 
    381 void ChromeClientEfl::print(Frame* frame)
    382 {
    383     notImplemented();
    384 }
    385 
    386 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    387 void ChromeClientEfl::reachedMaxAppCacheSize(int64_t spaceNeeded)
    388 {
    389     // FIXME: Free some space.
    390     notImplemented();
    391 }
    392 
    393 void ChromeClientEfl::reachedApplicationCacheOriginQuota(SecurityOrigin*)
    394 {
    395     notImplemented();
    396 }
    397 #endif
    398 
    399 #if ENABLE(TOUCH_EVENTS)
    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)
    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 
    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 
    460 void ChromeClientEfl::formStateDidChange(const Node*)
    461 {
    462     notImplemented();
    463 }
    464 
    465 void ChromeClientEfl::setCursor(const Cursor&)
    466 {
    467     notImplemented();
    468 }
    469 
    470 void ChromeClientEfl::requestGeolocationPermissionForFrame(Frame*, Geolocation*)
    471 {
    472     // See the comment in WebCore/page/ChromeClient.h
    473     notImplemented();
    474 }
    475 
    476 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*)
    477 {
    478     notImplemented();
    479 }
    480 
    481 void ChromeClientEfl::cancelGeolocationPermissionForFrame(Frame*, Geolocation*)
    482 {
    483     notImplemented();
    484 }
    485 
    486 void ChromeClientEfl::invalidateContents(const IntRect& updateRect, bool immediate)
    487 {
    488     notImplemented();
    489 }
    490 
    491 void ChromeClientEfl::invalidateWindow(const IntRect& updateRect, bool immediate)
    492 {
    493     notImplemented();
    494 }
    495 
    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 
    507 void ChromeClientEfl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
    508 {
    509     invalidateContentsAndWindow(updateRect, immediate);
    510 }
    511 
    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 
    517 void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*)
    518 {
    519     notImplemented();
    520 }
    521 
    522 void ChromeClientEfl::iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>)
    523 {
    524     notImplemented();
    525 }
    526 
    527 void ChromeClientEfl::chooseIconForFiles(const Vector<String>&, FileChooser*)
    528 {
    529     notImplemented();
    530 }
    531 
    532 void ChromeClientEfl::dispatchViewportDataDidChange(const ViewportArguments& arguments) const
    533 {
    534     ewk_view_viewport_attributes_set(m_view, arguments);
    535 }
    536 
    537 bool ChromeClientEfl::selectItemWritingDirectionIsNatural()
    538 {
    539     return true;
    540 }
    541 
    542 bool ChromeClientEfl::selectItemAlignmentFollowsMenuWritingDirection()
    543 {
    544     return false;
    545 }
    546 
    547 PassRefPtr<PopupMenu> ChromeClientEfl::createPopupMenu(PopupMenuClient* client) const
    548 {
    549     return adoptRef(new PopupMenuEfl(client));
    550 }
    551 
    552 PassRefPtr<SearchPopupMenu> ChromeClientEfl::createSearchPopupMenu(PopupMenuClient* client) const
    553 {
    554     return adoptRef(new SearchPopupMenuEfl(client));
    555 }
    556 
    557 }
    558