/*
    Copyright (C) 2009-2010 ProFUSION embedded systems
    Copyright (C) 2009-2010 Samsung Electronics

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

// Uncomment to view frame regions and debug messages
// #define EWK_FRAME_DEBUG

#include "config.h"
#include "ewk_frame.h"

#include "DocumentLoader.h"
#include "DocumentMarkerController.h"
#include "Editor.h"
#include "EventHandler.h"
#include "FocusController.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameLoaderClientEfl.h"
#include "FrameSelection.h"
#include "FrameView.h"
#include "HTMLCollection.h"
#include "HTMLHeadElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "HistoryItem.h"
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "IntSize.h"
#include "KURL.h"
#include "PlatformEvent.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMessagePortChannel.h"
#include "PlatformMouseEvent.h"
#include "PlatformTouchEvent.h"
#include "PlatformWheelEvent.h"
#include "ProgressTracker.h"
#include "ResourceRequest.h"
#include "ScriptController.h"
#include "ScriptValue.h"
#include "SharedBuffer.h"
#include "SubstituteData.h"
#include "WindowsKeyboardCodes.h"
#include "ewk_frame_private.h"
#include "ewk_private.h"
#include "ewk_security_origin_private.h"
#include "ewk_touch_event_private.h"
#include "ewk_view_private.h"
#include <Ecore_Input.h>
#include <Eina.h>
#include <Evas.h>
#include <eina_safety_checks.h>
#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>

static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame";

struct Ewk_Frame_Smart_Data {
    Evas_Object_Smart_Clipped_Data base;
    Evas_Object* self;
    Evas_Object* view;
#ifdef EWK_FRAME_DEBUG
    Evas_Object* region;
#endif
    WebCore::Frame* frame;
    Ewk_Text_With_Direction title;
    const char* uri;
    const char* name;
    bool editable : 1;
    bool hasDisplayedMixedContent : 1;
    bool hasRunMixedContent : 1;
};

struct Eina_Iterator_Ewk_Frame {
    Eina_Iterator base;
    Evas_Object* object;
    unsigned currentIndex;
};

#ifndef EWK_TYPE_CHECK
#define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
#else
#define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) \
    do { \
        const char* _tmp_otype = evas_object_type_get(ewkFrame); \
        if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) { \
            EINA_LOG_CRIT \
                ("%p (%s) is not of an ewk_frame!", ewkFrame, \
                _tmp_otype ? _tmp_otype : "(null)"); \
            return __VA_ARGS__; \
        } \
    } while (0)
#endif

#define EWK_FRAME_SD_GET(ewkFrame, pointer) \
    Ewk_Frame_Smart_Data* pointer = static_cast<Ewk_Frame_Smart_Data*>(evas_object_smart_data_get(ewkFrame))

#define EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, pointer, ...) \
    EWK_FRAME_TYPE_CHECK(ewkFrame, __VA_ARGS__); \
    EWK_FRAME_SD_GET(ewkFrame, pointer); \
    if (!pointer) { \
        CRITICAL("no smart data for object %p (%s)", \
                 ewkFrame, evas_object_type_get(ewkFrame)); \
        return __VA_ARGS__; \
    }

static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;

#ifdef EWK_FRAME_DEBUG
static inline void _ewk_frame_debug(Evas_Object* ewkFrame)
{
    Evas_Object* clip, * parent;
    Evas_Coord x, y, width, height, contentX, contentY, contentWidth, contentHeight;
    int red, green, blue, alpha, contentRed, contentGreen, contentBlue, contentAlpha;

    evas_object_color_get(ewkFrame, &red, &green, &blue, &alpha);
    evas_object_geometry_get(ewkFrame, &x, &y, &width, &height);

    clip = evas_object_clip_get(ewkFrame);
    evas_object_color_get(clip, &contentRed, &contentGreen, &contentBlue, &contentAlpha);
    evas_object_geometry_get(clip, &contentX, &contentY, &contentWidth, &contentHeight);

    EINA_LOG_DBG("%p: type=%s name=%s, visible=%d, color=%02x%02x%02x%02x, %d,%d+%dx%d, clipper=%p (%d, %02x%02x%02x%02x, %d,%d+%dx%d)\n",
            ewkFrame, evas_object_type_get(ewkFrame), evas_object_name_get(ewkFrame), evas_object_visible_get(ewkFrame),
            red, green, blue, alpha, x, y, width, height,
            clip, evas_object_visible_get(clip), contentRed, contentGreen, contentBlue, contentAlpha, contentX, contentY, contentWidth, contentHeight);
    parent = evas_object_smart_parent_get(ewkFrame);
    if (!parent)
        EINA_LOG_ERR("could not get parent object.\n");
    else
        _ewk_frame_debug(parent);
}
#endif

static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(const WebCore::Frame* frame)
{
    return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client());
}

static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* iterator, Evas_Object** data)
{
    EWK_FRAME_SD_GET_OR_RETURN(iterator->object, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);

    WebCore::FrameTree* tree = smartData->frame->tree(); // check if it's still valid
    EINA_SAFETY_ON_NULL_RETURN_VAL(tree, false);

    if (iterator->currentIndex < tree->childCount()) {
        *data = EWKPrivate::kitFrame(tree->child(iterator->currentIndex++));
        return true;
    }

    return false;
}

static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* iterator)
{
    return iterator->object;
}

static void _ewk_frame_smart_add(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET(ewkFrame, smartData);

    if (!smartData) {
        smartData = static_cast<Ewk_Frame_Smart_Data*>(calloc(1, sizeof(Ewk_Frame_Smart_Data)));
        if (!smartData) {
            CRITICAL("could not allocate Ewk_Frame_Smart_Data");
            return;
        }
        evas_object_smart_data_set(ewkFrame, smartData);
    }

    smartData->self = ewkFrame;

    _parent_sc.add(ewkFrame);
    evas_object_static_clip_set(smartData->base.clipper, false);
    evas_object_move(smartData->base.clipper, 0, 0);
    evas_object_resize(smartData->base.clipper, 0, 0);

#ifdef EWK_FRAME_DEBUG
    smartData->region = evas_object_rectangle_add(smartData->base.evas);
    static int i = 0;
    switch (i) {
    case 0:
        evas_object_color_set(smartData->region, 128, 0, 0, 128);
        break;
    case 1:
        evas_object_color_set(smartData->region, 0, 128, 0, 128);
        break;
    case 2:
        evas_object_color_set(smartData->region, 0, 0, 128, 128);
        break;
    case 3:
        evas_object_color_set(smartData->region, 128, 0, 0, 128);
        break;
    case 4:
        evas_object_color_set(smartData->region, 128, 128, 0, 128);
        break;
    case 5:
        evas_object_color_set(smartData->region, 128, 0, 128, 128);
        break;
    case 6:
        evas_object_color_set(smartData->region, 0, 128, 128, 128);
        break;
    default:
        break;
    }
    i++;
    if (i > 6)
        i = 0;

    evas_object_smart_member_add(smartData->region, ewkFrame);
    evas_object_hide(smartData->region);
#endif
}

static void _ewk_frame_smart_del(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET(ewkFrame, smartData);

    if (smartData) {
        if (smartData->frame) {
            WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(smartData->frame);
            flc->setWebFrame(0);
            EWK_FRAME_SD_GET(ewk_view_frame_main_get(smartData->view), mainSmartData);
            if (mainSmartData->frame == smartData->frame) // applying only for main frame is enough (will traverse through frame tree)
                smartData->frame->loader()->detachFromParent();
            smartData->frame = 0;
        }

        eina_stringshare_del(smartData->title.string);
        eina_stringshare_del(smartData->uri);
        eina_stringshare_del(smartData->name);
    }

    _parent_sc.del(ewkFrame);
}

static void _ewk_frame_smart_resize(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
{
    EWK_FRAME_SD_GET(ewkFrame, smartData);
    evas_object_resize(smartData->base.clipper, width, height);

#ifdef EWK_FRAME_DEBUG
    evas_object_resize(smartData->region, width, height);
    Evas_Coord x, y;
    evas_object_geometry_get(smartData->region, &x, &y, &width, &height);
    INFO("region=%p, visible=%d, geo=%d,%d + %dx%d",
        smartData->region, evas_object_visible_get(smartData->region), x, y, width, height);
    _ewk_frame_debug(ewkFrame);
#endif
}

static void _ewk_frame_smart_set(Evas_Smart_Class* api)
{
    evas_object_smart_clipped_smart_set(api);
    api->add = _ewk_frame_smart_add;
    api->del = _ewk_frame_smart_del;
    api->resize = _ewk_frame_smart_resize;
}

static inline Evas_Smart* _ewk_frame_smart_class_new(void)
{
    static Evas_Smart_Class smartClass = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR);
    static Evas_Smart* smart = 0;

    if (EINA_UNLIKELY(!smart)) {
        evas_object_smart_clipped_smart_set(&_parent_sc);
        _ewk_frame_smart_set(&smartClass);
        smart = evas_smart_class_new(&smartClass);
    }

    return smart;
}

Evas_Object* ewk_frame_view_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    return smartData->view;
}

Ewk_Security_Origin* ewk_frame_security_origin_get(const Evas_Object *ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document()->securityOrigin(), 0);

    return ewk_security_origin_new(smartData->frame->document()->securityOrigin());
}

Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    Eina_Iterator_Ewk_Frame* iterator = static_cast<Eina_Iterator_Ewk_Frame*>
                                  (calloc(1, sizeof(Eina_Iterator_Ewk_Frame)));
    if (!iterator)
        return 0;

    EINA_MAGIC_SET(&iterator->base, EINA_MAGIC_ITERATOR);
    iterator->base.next = FUNC_ITERATOR_NEXT(_ewk_frame_children_iterator_next);
    iterator->base.get_container = FUNC_ITERATOR_GET_CONTAINER(_ewk_frame_children_iterator_get_container);
    iterator->base.free = FUNC_ITERATOR_FREE(free);
    iterator->object = ewkFrame;
    iterator->currentIndex = 0;
    return &iterator->base;
}

Evas_Object* ewk_frame_child_find(Evas_Object* ewkFrame, const char* name)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    WTF::String frameName = WTF::String::fromUTF8(name);
    return EWKPrivate::kitFrame(smartData->frame->tree()->find(WTF::AtomicString(frameName)));
}

Eina_Bool ewk_frame_uri_set(Evas_Object* ewkFrame, const char* uri)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri));
    WebCore::ResourceRequest req(kurl);
    WebCore::FrameLoader* loader = smartData->frame->loader();
    loader->load(WebCore::FrameLoadRequest(smartData->frame, req));
    return true;
}

const char* ewk_frame_uri_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    return smartData->uri;
}

const Ewk_Text_With_Direction* ewk_frame_title_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    return &smartData->title;
}

const char* ewk_frame_name_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);

    if (!smartData->frame) {
        ERR("could not get name of uninitialized frame.");
        return 0;
    }

    const WTF::String frameName = smartData->frame->tree()->uniqueName();

    if ((smartData->name) && (smartData->name == frameName))
        return smartData->name;

    eina_stringshare_replace_length(&(smartData->name), frameName.utf8().data(), frameName.length());

    return smartData->name;
}

Eina_Bool ewk_frame_contents_size_get(const Evas_Object* ewkFrame, Evas_Coord* width, Evas_Coord* height)
{
    if (width)
        *width = 0;
    if (height)
        *height = 0;
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    if (!smartData->frame || !smartData->frame->view())
        return false;
    if (width)
        *width = smartData->frame->view()->contentsWidth();
    if (height)
        *height = smartData->frame->view()->contentsHeight();
    return true;
}

static Eina_Bool _ewk_frame_contents_set_internal(Ewk_Frame_Smart_Data* smartData, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri, const char* unreachableUri)
{
    size_t length = strlen(contents);
    if (contentsSize < 1 || contentsSize > length)
        contentsSize = length;
    if (!mimeType)
        mimeType = "text/html";
    if (!encoding)
        encoding = "UTF-8";
    if (!baseUri)
        baseUri = "about:blank";

    WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(baseUri));
    WebCore::KURL unreachableKURL;
    if (unreachableUri)
        unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachableUri));
    else
        unreachableKURL = WebCore::KURL();

    WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contentsSize);
    WebCore::SubstituteData substituteData
        (buffer.release(),
        WTF::String::fromUTF8(mimeType),
        WTF::String::fromUTF8(encoding),
        baseKURL, unreachableKURL);
    WebCore::ResourceRequest request(baseKURL);

    smartData->frame->loader()->load(WebCore::FrameLoadRequest(smartData->frame, request, substituteData));
    return true;
}

Eina_Bool ewk_frame_contents_set(Evas_Object* ewkFrame, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(contents, false);
    return _ewk_frame_contents_set_internal
               (smartData, contents, contentsSize, mimeType, encoding, baseUri, 0);
}

Eina_Bool ewk_frame_contents_alternate_set(Evas_Object* ewkFrame, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri, const char* unreachableUri)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(contents, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(unreachableUri, false);
    return _ewk_frame_contents_set_internal
               (smartData, contents, contentsSize, mimeType, encoding, baseUri,
               unreachableUri);
}

const char* ewk_frame_script_execute(Evas_Object* ewkFrame, const char* script)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(script, 0);

    WTF::String resultString;
    JSC::JSValue result = smartData->frame->script()->executeScript(WTF::String::fromUTF8(script), true).jsValue();

    if (!smartData->frame) // In case the script removed our frame from the page.
        return 0;

    if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
        return 0;

    JSC::ExecState* exec = smartData->frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec();
    JSC::JSLockHolder lock(exec);
    resultString = result.toString(exec)->value(exec);
    return eina_stringshare_add(resultString.utf8().data());
}

Eina_Bool ewk_frame_editable_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    return smartData->editable;
}

Eina_Bool ewk_frame_editable_set(Evas_Object* ewkFrame, Eina_Bool editable)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    editable = !!editable;
    if (smartData->editable == editable)
        return true;
    smartData->editable = editable;
    if (editable)
        smartData->frame->editor()->applyEditingStyleToBodyElement();
    return true;
}

const char* ewk_frame_selection_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    WTF::CString selectedText = smartData->frame->editor()->selectedText().utf8();
    if (selectedText.isNull())
        return 0;
    return eina_stringshare_add(selectedText.data());
}

Eina_Bool ewk_frame_text_search(const Evas_Object* ewkFrame, const char* text, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);

    return smartData->frame->editor()->findString(WTF::String::fromUTF8(text), forward, caseSensitive, wrap, true);
}

unsigned int ewk_frame_text_matches_mark(Evas_Object* ewkFrame, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);

    smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
    return smartData->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), 0, caseSensitive, limit, true, 0);
}

Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);

    smartData->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch);
    return true;
}

Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* ewkFrame, Eina_Bool highlight)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
    return true;
}

Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    return smartData->frame->editor()->markedTextMatchesAreHighlighted();
}

/**
 * Comparison function used by ewk_frame_text_matches_nth_pos_get
 */
static bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& begin, const WebCore::IntRect& end)
{
    return (begin.y() < end.y() || (begin.y() == end.y() && begin.x() < end.x()));
}

/**
 * Predicate used by ewk_frame_text_matches_nth_pos_get
 */
static bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& rect)
{
    return (rect.x() < 0 || rect.y() < 0);
}

Eina_Bool ewk_frame_text_matches_nth_pos_get(const Evas_Object* ewkFrame, size_t number, int* x, int* y)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);

    Vector<WebCore::IntRect> intRects = smartData->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch);

    /* remove useless values */
    std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value);

    if (intRects.isEmpty() || number > intRects.size())
        return false;

    std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than);

    if (x)
        *x = intRects[number - 1].x();
    if (y)
        *y = intRects[number - 1].y();
    return true;
}

Eina_Bool ewk_frame_stop(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->loader()->stopAllLoaders();
    return true;
}

Eina_Bool ewk_frame_reload(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->loader()->reload();
    return true;
}

Eina_Bool ewk_frame_reload_full(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->loader()->reload(true);
    return true;
}

Eina_Bool ewk_frame_back(Evas_Object* ewkFrame)
{
    return ewk_frame_navigate(ewkFrame, -1);
}

Eina_Bool ewk_frame_forward(Evas_Object* ewkFrame)
{
    return ewk_frame_navigate(ewkFrame, 1);
}

Eina_Bool ewk_frame_navigate(Evas_Object* ewkFrame, int steps)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    WebCore::Page* page = smartData->frame->page();
    if (!page->canGoBackOrForward(steps))
        return false;
    page->goBackOrForward(steps);
    return true;
}

Eina_Bool ewk_frame_back_possible(Evas_Object* ewkFrame)
{
    return ewk_frame_navigate_possible(ewkFrame, -1);
}

Eina_Bool ewk_frame_forward_possible(Evas_Object* ewkFrame)
{
    return ewk_frame_navigate_possible(ewkFrame, 1);
}

Eina_Bool ewk_frame_navigate_possible(Evas_Object* ewkFrame, int steps)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    WebCore::Page* page = smartData->frame->page();
    return page->canGoBackOrForward(steps);
}

float ewk_frame_page_zoom_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
    return smartData->frame->pageZoomFactor();
}

Eina_Bool ewk_frame_page_zoom_set(Evas_Object* ewkFrame, float pageZoomFactor)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->setPageZoomFactor(pageZoomFactor);
    return true;
}

float ewk_frame_text_zoom_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
    return smartData->frame->textZoomFactor();
}

Eina_Bool ewk_frame_text_zoom_set(Evas_Object* ewkFrame, float textZoomFactor)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    smartData->frame->setTextZoomFactor(textZoomFactor);
    return true;
}

void ewk_frame_hit_test_free(Ewk_Hit_Test* hitTest)
{
    EINA_SAFETY_ON_NULL_RETURN(hitTest);
    eina_stringshare_del(hitTest->title.string);
    eina_stringshare_del(hitTest->alternate_text);
    eina_stringshare_del(hitTest->link.text);
    eina_stringshare_del(hitTest->link.url);
    eina_stringshare_del(hitTest->link.title);
    eina_stringshare_del(hitTest->image_uri);
    eina_stringshare_del(hitTest->media_uri);
    delete hitTest;
}

Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* ewkFrame, int x, int y)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);

    WebCore::FrameView* view = smartData->frame->view();
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->contentRenderer(), 0);

    WebCore::HitTestResult result = smartData->frame->eventHandler()->hitTestResultAtPoint
                                        (view->windowToContents(WebCore::IntPoint(x, y)), 
                                        WebCore::HitTestRequest::ReadOnly | WebCore::HitTestRequest::Active | WebCore::HitTestRequest::IgnoreClipping | WebCore::HitTestRequest::DisallowShadowContent);

    if (result.scrollbar())
        return 0;
    if (!result.innerNode())
        return 0;

    Ewk_Hit_Test* hitTest = new Ewk_Hit_Test;
    // FIXME: This should probably use pointInMainFrame, if it is to match the documentation of ewk_hit_test.
    hitTest->x = result.pointInInnerNodeFrame().x();
    hitTest->y = result.pointInInnerNodeFrame().y();
#if 0
    // FIXME
    hitTest->bounding_box.x = result.boundingBox().x();
    hitTest->bounding_box.y = result.boundingBox().y();
    hitTest->bounding_box.width = result.boundingBox().width();
    hitTest->bounding_box.height = result.boundingBox().height();
#else
    hitTest->bounding_box.x = 0;
    hitTest->bounding_box.y = 0;
    hitTest->bounding_box.w = 0;
    hitTest->bounding_box.h = 0;
#endif

    WebCore::TextDirection direction;
    hitTest->title.string = eina_stringshare_add(result.title(direction).utf8().data());
    hitTest->title.direction = (direction == WebCore::LTR) ? EWK_TEXT_DIRECTION_LEFT_TO_RIGHT : EWK_TEXT_DIRECTION_RIGHT_TO_LEFT;
    hitTest->alternate_text = eina_stringshare_add(result.altDisplayString().utf8().data());
    if (result.innerNonSharedNode() && result.innerNonSharedNode()->document()
        && result.innerNonSharedNode()->document()->frame())
        hitTest->frame = EWKPrivate::kitFrame(result.innerNonSharedNode()->document()->frame());

    hitTest->link.text = eina_stringshare_add(result.textContent().utf8().data());
    hitTest->link.url = eina_stringshare_add(result.absoluteLinkURL().string().utf8().data());
    hitTest->link.title = eina_stringshare_add(result.titleDisplayString().utf8().data());
    hitTest->link.target_frame = EWKPrivate::kitFrame(result.targetFrame());

    hitTest->image_uri = eina_stringshare_add(result.absoluteImageURL().string().utf8().data());
    hitTest->media_uri = eina_stringshare_add(result.absoluteMediaURL().string().utf8().data());

    int context = EWK_HIT_TEST_RESULT_CONTEXT_DOCUMENT;

    if (!result.absoluteLinkURL().isEmpty())
        context |= EWK_HIT_TEST_RESULT_CONTEXT_LINK;
    if (!result.absoluteImageURL().isEmpty())
        context |= EWK_HIT_TEST_RESULT_CONTEXT_IMAGE;
    if (!result.absoluteMediaURL().isEmpty())
        context |= EWK_HIT_TEST_RESULT_CONTEXT_MEDIA;
    if (result.isSelected())
        context |= EWK_HIT_TEST_RESULT_CONTEXT_SELECTION;
    if (result.isContentEditable())
        context |= EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE;

    hitTest->context = static_cast<Ewk_Hit_Test_Result_Context>(context);

    return hitTest;
}

Eina_Bool
ewk_frame_scroll_add(Evas_Object* ewkFrame, int deltaX, int deltaY)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    smartData->frame->view()->scrollBy(WebCore::IntSize(deltaX, deltaY));
    return true;
}

Eina_Bool
ewk_frame_scroll_set(Evas_Object* ewkFrame, int x, int y)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    smartData->frame->view()->setScrollPosition(WebCore::IntPoint(x, y));
    return true;
}

Eina_Bool
ewk_frame_scroll_size_get(const Evas_Object* ewkFrame, int* width, int* height)
{
    if (width)
        *width = 0;
    if (height)
        *height = 0;
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    WebCore::IntPoint point = smartData->frame->view()->maximumScrollPosition();
    if (width)
        *width = point.x();
    if (height)
        *height = point.y();
    return true;
}

Eina_Bool
ewk_frame_scroll_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
{
    if (x)
        *x = 0;
    if (y)
        *y = 0;
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    WebCore::IntPoint pos = smartData->frame->view()->scrollPosition();
    if (x)
        *x = pos.x();
    if (y)
        *y = pos.y();
    return true;
}

Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* ewkFrame, Eina_Bool includeScrollbars, int* x, int* y, int* width, int* height)
{
    if (x)
        *x = 0;
    if (y)
        *y = 0;
    if (width)
        *width = 0;
    if (height)
        *height = 0;
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    WebCore::IntRect rect = smartData->frame->view()->visibleContentRect(includeScrollbars ? WebCore::ScrollableArea::IncludeScrollbars : WebCore::ScrollableArea::ExcludeScrollbars);
    if (x)
        *x = rect.x();
    if (y)
        *y = rect.y();
    if (width)
        *width = rect.width();
    if (height)
        *height = rect.height();
    return true;
}

Eina_Bool ewk_frame_paint_full_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
    return smartData->frame->view()->paintsEntireContents();
}

void ewk_frame_paint_full_set(Evas_Object* ewkFrame, Eina_Bool flag)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
    EINA_SAFETY_ON_NULL_RETURN(smartData->frame->view());
    smartData->frame->view()->setPaintsEntireContents(flag);
}

Eina_Bool ewk_frame_feed_focus_in(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    WebCore::FocusController* focusController = smartData->frame->page()->focusController();
    focusController->setFocusedFrame(smartData->frame);
    return true;
}

Eina_Bool ewk_frame_feed_focus_out(Evas_Object*)
{
    // TODO: what to do on focus out?
    ERR("what to do?");
    return false;
}

Eina_Bool ewk_frame_focused_element_geometry_get(const Evas_Object *ewkFrame, int *x, int *y, int *w, int *h)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    WebCore::Document* document = smartData->frame->document();
    if (!document)
        return false;
    WebCore::Node* focusedNode = document->focusedNode();
    if (!focusedNode)
        return false;
    WebCore::IntRect nodeRect = focusedNode->pixelSnappedBoundingBox();
    if (x)
        *x = nodeRect.x();
    if (y)
        *y = nodeRect.y();
    if (w)
        *w = nodeRect.width();
    if (h)
        *h = nodeRect.height();
    return true;
}

Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* ewkFrame, const Evas_Event_Mouse_Wheel* wheelEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(wheelEvent, false);

    WebCore::FrameView* view = smartData->frame->view();
    DBG("ewkFrame=%p, view=%p, direction=%d, z=%d, pos=%d,%d",
        ewkFrame, view, wheelEvent->direction, wheelEvent->z, wheelEvent->canvas.x, wheelEvent->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);

    WebCore::PlatformWheelEvent event(wheelEvent);
    return smartData->frame->eventHandler()->handleWheelEvent(event);
}

Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* ewkFrame, const Evas_Event_Mouse_Down* downEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, false);

    WebCore::FrameView* view = smartData->frame->view();
    DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
        ewkFrame, view, downEvent->button, downEvent->canvas.x, downEvent->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);

    Evas_Coord x, y;
    evas_object_geometry_get(smartData->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
    return smartData->frame->eventHandler()->handleMousePressEvent(event);
}

Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* ewkFrame, const Evas_Event_Mouse_Up* upEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, false);

    WebCore::FrameView* view = smartData->frame->view();
    DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
        ewkFrame, view, upEvent->button, upEvent->canvas.x, upEvent->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);

    Evas_Coord x, y;
    evas_object_geometry_get(smartData->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(upEvent, WebCore::IntPoint(x, y));
    return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
}

Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* ewkFrame, const Evas_Event_Mouse_Move* moveEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(moveEvent, false);

    WebCore::FrameView* view = smartData->frame->view();
    DBG("ewkFrame=%p, view=%p, pos: old=%d,%d, new=%d,%d, buttons=%d",
        ewkFrame, view, moveEvent->cur.canvas.x, moveEvent->cur.canvas.y,
        moveEvent->prev.canvas.x, moveEvent->prev.canvas.y, moveEvent->buttons);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);

    Evas_Coord x, y;
    evas_object_geometry_get(smartData->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(moveEvent, WebCore::IntPoint(x, y));
    return smartData->frame->eventHandler()->mouseMoved(event);
}

Eina_Bool ewk_frame_feed_touch_event(Evas_Object* ewkFrame, Ewk_Touch_Event_Type action, Eina_List* points, unsigned modifiers)
{
#if ENABLE(TOUCH_EVENTS)
    EINA_SAFETY_ON_NULL_RETURN_VAL(points, false);
    EWK_FRAME_SD_GET(ewkFrame, smartData);

    if (!smartData || !smartData->frame || !ewk_view_need_touch_events_get(smartData->view))
        return false;

    Evas_Coord x, y;
    evas_object_geometry_get(smartData->view, &x, &y, 0, 0);

    return smartData->frame->eventHandler()->handleTouchEvent(EWKPrivate::platformTouchEvent(x, y, points, action, modifiers));
#else
    UNUSED_PARAM(ewkFrame);
    UNUSED_PARAM(action);
    UNUSED_PARAM(points);
    UNUSED_PARAM(modifiers);
    return false;
#endif
}

static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent& keyEvent)
{
    WebCore::ScrollDirection direction;
    WebCore::ScrollGranularity granularity;

    int keyCode = keyEvent.windowsVirtualKeyCode();

    switch (keyCode) {
    case VK_SPACE:
        granularity = WebCore::ScrollByPage;
        if (keyEvent.shiftKey())
            direction = WebCore::ScrollUp;
        else
            direction = WebCore::ScrollDown;
        break;
    case VK_NEXT:
        granularity = WebCore::ScrollByPage;
        direction = WebCore::ScrollDown;
        break;
    case VK_PRIOR:
        granularity = WebCore::ScrollByPage;
        direction = WebCore::ScrollUp;
        break;
    case VK_HOME:
        granularity = WebCore::ScrollByDocument;
        direction = WebCore::ScrollUp;
        break;
    case VK_END:
        granularity = WebCore::ScrollByDocument;
        direction = WebCore::ScrollDown;
        break;
    case VK_LEFT:
        granularity = WebCore::ScrollByLine;
        direction = WebCore::ScrollLeft;
        break;
    case VK_RIGHT:
        granularity = WebCore::ScrollByLine;
        direction = WebCore::ScrollRight;
        break;
    case VK_UP:
        direction = WebCore::ScrollUp;
        if (keyEvent.ctrlKey())
            granularity = WebCore::ScrollByDocument;
        else
            granularity = WebCore::ScrollByLine;
        break;
    case VK_DOWN:
        direction = WebCore::ScrollDown;
        if (keyEvent.ctrlKey())
            granularity = WebCore::ScrollByDocument;
        else
            granularity = WebCore::ScrollByLine;
        break;
    default:
        return false;
    }

    if (frame->eventHandler()->scrollOverflow(direction, granularity))
        return false;

    frame->view()->scroll(direction, granularity);
    return true;
}

Eina_Bool ewk_frame_feed_key_down(Evas_Object* ewkFrame, const Evas_Event_Key_Down* downEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, false);

    DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
        ewkFrame, downEvent->keyname, downEvent->key ? downEvent->key : "", downEvent->string ? downEvent->string : "");

    WebCore::PlatformKeyboardEvent event(downEvent);
    if (smartData->frame->eventHandler()->keyEvent(event))
        return true;

    return _ewk_frame_handle_key_scrolling(smartData->frame, event);
}

Eina_Bool ewk_frame_feed_key_up(Evas_Object* ewkFrame, const Evas_Event_Key_Up* upEvent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, false);

    DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
        ewkFrame, upEvent->keyname, upEvent->key ? upEvent->key : "", upEvent->string ? upEvent->string : "");

    WebCore::PlatformKeyboardEvent event(upEvent);
    return smartData->frame->eventHandler()->keyEvent(event);
}

Ewk_Text_Selection_Type ewk_frame_text_selection_type_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EWK_TEXT_SELECTION_NONE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EWK_TEXT_SELECTION_NONE);

    WebCore::FrameSelection* controller = smartData->frame->selection();
    if (!controller)
        return EWK_TEXT_SELECTION_NONE;

    return static_cast<Ewk_Text_Selection_Type>(controller->selectionType());
}

/* internal methods ****************************************************/

/**
 * @internal
 *
 * Creates a new EFL WebKit Frame object.
 *
 * Frames are low level entries contained in a page that is contained
 * by a view. Usually one operates on the view and not directly on the
 * frame.
 *
 * @param canvas canvas where to create the frame object
 *
 * @return a new frame object or @c 0 on failure
 */
Evas_Object* ewk_frame_add(Evas* canvas)
{
    return evas_object_smart_add(canvas, _ewk_frame_smart_class_new());
}

/**
 * @internal
 *
 * Initialize frame based on actual WebKit frame.
 *
 * This is internal and should never be called by external users.
 */
bool ewk_frame_init(Evas_Object* ewkFrame, Evas_Object* view, WebCore::Frame* frame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    if (!smartData->frame) {
        WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(frame);
        frameLoaderClient->setWebFrame(ewkFrame);
        smartData->frame = frame;
        smartData->view = view;
        frame->init();
        return true;
    }

    ERR("frame %p already set for %p, ignored new %p",
        smartData->frame, ewkFrame, frame);
    return false;
}

/**
 * @internal
 *
 * Adds child to the frame.
 */
bool ewk_frame_child_add(Evas_Object* ewkFrame, WTF::PassRefPtr<WebCore::Frame> child, const WTF::String& name, const WebCore::KURL& url, const WTF::String& referrer)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    char buffer[256];
    Evas_Object* frame;
    WebCore::Frame* coreFrame;

    frame = ewk_frame_add(smartData->base.evas);
    if (!frame) {
        ERR("Could not create ewk_frame object.");
        return false;
    }

    coreFrame = child.get();
    if (coreFrame->tree())
        coreFrame->tree()->setName(name);
    else
        ERR("no tree for child object");
    smartData->frame->tree()->appendChild(child);

    if (!ewk_frame_init(frame, smartData->view, coreFrame)) {
        evas_object_del(frame);
        return false;
    }
    snprintf(buffer, sizeof(buffer), "EWK_Frame:child/%s", name.utf8().data());
    evas_object_name_set(frame, buffer);
    evas_object_smart_member_add(frame, ewkFrame);
    evas_object_show(frame);

    // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
    if (!coreFrame->page()) {
        evas_object_del(frame);
        return true;
    }

    evas_object_smart_callback_call(smartData->view, "frame,created", frame);
    smartData->frame->loader()->loadURLIntoChildFrame(url, referrer, coreFrame);

    // The frame's onload handler may have removed it from the document.
    // See fast/dom/null-page-show-modal-dialog-crash.html for an example.
    if (!coreFrame->tree()->parent()) {
        evas_object_del(frame);
        return true;
    }

    return true;
}

/**
 * @internal
 * Change the ewk view this frame is associated with.
 *
 * @param ewkFrame The ewk frame to act upon.
 * @param newParent The new view that will be set as the parent of the frame.
 */
void ewk_frame_view_set(Evas_Object* ewkFrame, Evas_Object* newParent)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);

    evas_object_smart_member_del(ewkFrame);
    evas_object_smart_member_add(ewkFrame, newParent);

    smartData->view = newParent;
}

/**
 * @internal
 * Frame was destroyed by loader, remove internal reference.
 */
void ewk_frame_core_gone(Evas_Object* ewkFrame)
{
    DBG("ewkFrame=%p", ewkFrame);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    smartData->frame = 0;
}

/**
 * @internal
 * Reports cancellation of a client redirect.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "redirect,cancelled"
 */
void ewk_frame_redirect_cancelled(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "redirect,cancelled", 0);
}

/**
 * @internal
 * Reports receipt of server redirect for provisional load.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "redirect,load,provisional"
 */
void ewk_frame_redirect_provisional_load(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "redirect,load,provisional", 0);
}

/**
 * @internal
 * Reports that a client redirect will be performed.
 *
 * @param ewkFrame Frame.
 * @param url Redirection URL.
 *
 * Emits signal: "redirect,requested"
 */
void ewk_frame_redirect_requested(Evas_Object* ewkFrame, const char* url)
{
    evas_object_smart_callback_call(ewkFrame, "redirect,requested", (void*)url);
}

/**
 * @internal
 * Reports a resource will be requested. User may override behavior of webkit by
 * changing values in @param request.
 *
 * @param ewkFrame Frame.
 * @param messages Messages containing the request details that user may override and a
 * possible redirect reponse. Whenever values on this struct changes, it must be properly
 * malloc'd as it will be freed afterwards.
 *
 * Emits signal: "resource,request,willsend"
 */
void ewk_frame_request_will_send(Evas_Object* ewkFrame, Ewk_Frame_Resource_Messages* messages)
{
    evas_object_smart_callback_call(ewkFrame, "resource,request,willsend", messages);
}

/**
 * @internal
 * Reports that there's a new resource.
 *
 * @param ewkFrame Frame.
 * @param request New request details. No changes are allowed to fields.
 *
 * Emits signal: "resource,request,new"
 */
void ewk_frame_request_assign_identifier(Evas_Object* ewkFrame, const Ewk_Frame_Resource_Request* request)
{
    evas_object_smart_callback_call(ewkFrame, "resource,request,new", (void*)request);
}

/**
 * @internal
 * Reports that a response to a resource request was received.
 *
 * @param ewkFrame Frame.
 * @param request Response details. No changes are allowed to fields.
 *
 * Emits signal: "resource,response,received"
 */
void ewk_frame_response_received(Evas_Object* ewkFrame, Ewk_Frame_Resource_Response* response)
{
    evas_object_smart_callback_call(ewkFrame, "resource,response,received", response);
}

/**
 * @internal
 * Reports that first navigation occurred
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "navigation,first"
 */
void ewk_frame_did_perform_first_navigation(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "navigation,first", 0);
}

/**
 * @internal
 * Reports frame will be saved to current state
 *
 * @param ewkFrame Frame.
 * @param item History item to save details to.
 *
 * Emits signal: "state,save"
 */
void ewk_frame_view_state_save(Evas_Object* ewkFrame, WebCore::HistoryItem*)
{
    evas_object_smart_callback_call(ewkFrame, "state,save", 0);
}

/**
 * @internal
 * Reports the frame committed load.
 *
 * Emits signal: "load,committed" with no parameters.
 */
void ewk_frame_load_committed(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "load,committed", 0);
}

/**
 * @internal
 * Reports the frame started loading something.
 *
 * Emits signal: "load,started" with no parameters.
 */
void ewk_frame_load_started(Evas_Object* ewkFrame)
{
    Evas_Object* mainFrame;
    DBG("ewkFrame=%p", ewkFrame);
    evas_object_smart_callback_call(ewkFrame, "load,started", 0);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_load_started(smartData->view, ewkFrame);

    mainFrame = ewk_view_frame_main_get(smartData->view);
    if (mainFrame == ewkFrame)
        ewk_view_frame_main_load_started(smartData->view);
}

/**
 * @internal
 * Reports the frame started provisional load.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "load,provisional" with no parameters.
 */
void ewk_frame_load_provisional(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "load,provisional", 0);
}

/**
 * @internal
 * Reports the frame provisional load failed.
 *
 * @param ewkFrame Frame.
 * @param error Load error.
 *
 * Emits signal: "load,provisional,failed" with pointer to Ewk_Frame_Load_Error.
 */
void ewk_frame_load_provisional_failed(Evas_Object* ewkFrame, const Ewk_Frame_Load_Error* error)
{
    evas_object_smart_callback_call(ewkFrame, "load,provisional,failed", const_cast<Ewk_Frame_Load_Error*>(error));
}

/**
 * @internal
 * Reports the frame finished first layout.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "load,firstlayout,finished" with no parameters.
 */
void ewk_frame_load_firstlayout_finished(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "load,firstlayout,finished", 0);
}

/**
 * @internal
 * Reports the frame finished first non empty layout.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "load,nonemptylayout,finished" with no parameters.
 */
void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "load,nonemptylayout,finished", 0);
}

/**
 * @internal
 * Reports the loading of a document has finished on frame.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "load,document,finished" with no parameters.
 */
void ewk_frame_load_document_finished(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "load,document,finished", 0);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_load_document_finished(smartData->view, ewkFrame);
}

/**
 * @internal
 * Reports load finished, optionally with error information.
 *
 * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error
 * if any error, or @c NULL if successful load.
 *
 * @note there should notbe any error stuff here, but trying to be
 *       compatible with previous WebKit.
 */
void ewk_frame_load_finished(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
{
    Ewk_Frame_Load_Error buffer, *error;
    if (!errorDomain) {
        DBG("ewkFrame=%p, success.", ewkFrame);
        error = 0;
    } else {
        DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
            ewkFrame, errorDomain, errorCode, isCancellation,
            errorDescription, failingUrl);

        buffer.domain = errorDomain;
        buffer.code = errorCode;
        buffer.is_cancellation = isCancellation;
        buffer.description = errorDescription;
        buffer.failing_url = failingUrl;
        buffer.resource_identifier = 0;
        buffer.frame = ewkFrame;
        error = &buffer;
    }
    evas_object_smart_callback_call(ewkFrame, "load,finished", error);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_load_finished(smartData->view, error);
}

/**
 * @internal
 * Reports resource load finished.
 *
 * Emits signal: "load,resource,finished" with the resource
 * request identifier.
 */
void ewk_frame_load_resource_finished(Evas_Object* ewkFrame, unsigned long identifier)
{
    evas_object_smart_callback_call(ewkFrame, "load,resource,finished", &identifier);
}

/**
 * @internal
 * Reports resource load failure, with error information.
 *
 * Emits signal: "load,resource,failed" with the error information.
 */
void ewk_frame_load_resource_failed(Evas_Object* ewkFrame, Ewk_Frame_Load_Error* error)
{
    evas_object_smart_callback_call(ewkFrame, "load,resource,failed", error);
}

/**
 * @internal
 * Reports load failed with error information.
 *
 * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
 */
void ewk_frame_load_error(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
{
    Ewk_Frame_Load_Error error;

    DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
        ewkFrame, errorDomain, errorCode, isCancellation,
        errorDescription, failingUrl);

    EINA_SAFETY_ON_NULL_RETURN(errorDomain);

    error.code = errorCode;
    error.is_cancellation = isCancellation;
    error.domain = errorDomain;
    error.description = errorDescription;
    error.failing_url = failingUrl;
    error.resource_identifier = 0;
    error.frame = ewkFrame;
    evas_object_smart_callback_call(ewkFrame, "load,error", &error);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_load_error(smartData->view, &error);
}

/**
 * @internal
 * Reports load progress changed.
 *
 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
 */
void ewk_frame_load_progress_changed(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    EINA_SAFETY_ON_NULL_RETURN(smartData->frame);

    // TODO: this is per page, there should be a way to have per-frame.
    double progress = smartData->frame->page()->progress()->estimatedProgress();

    DBG("ewkFrame=%p (p=%0.3f)", ewkFrame, progress);

    evas_object_smart_callback_call(ewkFrame, "load,progress", &progress);
    ewk_view_load_progress_changed(smartData->view);
}

/**
 * @internal
 *
 * Reports contents size changed.
 */
void ewk_frame_contents_size_changed(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
{
    Evas_Coord size[2] = {width, height};
    evas_object_smart_callback_call(ewkFrame, "contents,size,changed", size);
}

/**
 * @internal
 *
 * Reports title changed.
 */
void ewk_frame_title_set(Evas_Object* ewkFrame, const Ewk_Text_With_Direction* title)
{
    DBG("ewkFrame=%p, title=%s, direction=%s", ewkFrame, title->string ? title->string : "(null)", title->direction == EWK_TEXT_DIRECTION_LEFT_TO_RIGHT ? "ltr" : "rtl");
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    if (!eina_stringshare_replace(&smartData->title.string, title->string) && (smartData->title.direction == title->direction))
        return;
    smartData->title.direction = title->direction;
    evas_object_smart_callback_call(ewkFrame, "title,changed", (void*)title);
}

/**
 * @internal
 *
 * Creates a view.
 */
void ewk_frame_view_create_for_view(Evas_Object* ewkFrame, Evas_Object* view)
{
    DBG("ewkFrame=%p, view=%p", ewkFrame, view);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
    Evas_Coord width, height;

    evas_object_geometry_get(view, 0, 0, &width, &height);

    WebCore::IntSize size(width, height);
    int red, green, blue, alpha;
    WebCore::Color background;

    ewk_view_bg_color_get(view, &red, &green, &blue, &alpha);
    if (!alpha)
        background = WebCore::Color(0, 0, 0, 0);
    else if (alpha == 255)
        background = WebCore::Color(red, green, blue, alpha);
    else
        background = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);

    smartData->frame->createView(size, background, !alpha);
    if (!smartData->frame->view())
        return;

    smartData->frame->view()->setEvasObject(ewkFrame);

    ewk_frame_mixed_content_displayed_set(ewkFrame, false);
    ewk_frame_mixed_content_run_set(ewkFrame, false);
}

ssize_t ewk_frame_source_get(const Evas_Object* ewkFrame, char** frameSource)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), -1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(frameSource, -1);

    StringBuilder builder;
    *frameSource = 0; // Saves 0 to pointer until it's not allocated.

    if (!ewk_frame_uri_get(ewkFrame))
        return -1;

    if (!smartData->frame->document()->isHTMLDocument()) {
        // FIXME: Support others documents.
        WARN("Only HTML documents are supported");
        return -1;
    }

    // Look for <html> tag. If it exists, the node contatins all document's source.
    WebCore::Node* documentNode = smartData->frame->document()->documentElement();
    if (documentNode)
        for (WebCore::Node* node = documentNode->firstChild(); node; node = node->parentElement()) {
            if (node->hasTagName(WebCore::HTMLNames::htmlTag)) {
                WebCore::HTMLElement* element = static_cast<WebCore::HTMLElement*>(node);
                if (element)
                    builder.append(element->outerHTML());
                break;
            }
        }

    CString utf8String = builder.toString().utf8();
    size_t sourceLength = utf8String.length();
    *frameSource = static_cast<char*>(malloc(sourceLength + 1));
    if (!*frameSource) {
        CRITICAL("Could not allocate memory.");
        return -1;
    }

    strncpy(*frameSource, utf8String.data(), sourceLength);
    (*frameSource)[sourceLength] = '\0';

    return sourceLength;
}

Eina_List* ewk_frame_resources_location_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), 0);

    Eina_List* listOfImagesLocation = 0;

    // Get src attibute of images and saves them to the Eina_List.
    RefPtr<WebCore::HTMLCollection> images = smartData->frame->document()->images();
    for (size_t index = 0; index < images->length(); ++index) {
        WebCore::HTMLImageElement* imageElement = static_cast<WebCore::HTMLImageElement*>(images->item(index));
        if (!imageElement || imageElement->src().isNull() || imageElement->src().isEmpty())
            continue;

        WTF::String imageLocation = WebCore::decodeURLEscapeSequences(imageElement->src().string());
        // Look for duplicated location.
        Eina_List* listIterator = 0;
        void* data = 0;
        Eina_Bool found = false;
        EINA_LIST_FOREACH(listOfImagesLocation, listIterator, data)
            if ((found = !strcmp(static_cast<char*>(data), imageLocation.utf8().data())))
                break;
        if (found)
            continue;

        const char* imageLocationCopy = eina_stringshare_add(imageLocation.utf8().data());
        if (!imageLocationCopy)
            goto out_of_memory_handler;
        listOfImagesLocation = eina_list_append(listOfImagesLocation, imageLocationCopy);
        if (eina_error_get())
            goto out_of_memory_handler;
    }
    // FIXME: Get URL others resources (plugins, css, media files).
    return listOfImagesLocation;

out_of_memory_handler:
    CRITICAL("Could not allocate memory.");
    void* data;
    EINA_LIST_FREE(listOfImagesLocation, data)
        free(data);
    return 0;
}

const char* ewk_frame_plain_text_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);

    if (!smartData->frame->document())
        return 0;

    WebCore::Element* documentElement = smartData->frame->document()->documentElement();

    if (!documentElement)
        return 0;

    return eina_stringshare_add(documentElement->innerText().utf8().data());
}

Eina_Bool ewk_frame_mixed_content_displayed_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    return smartData->hasDisplayedMixedContent;
}

Eina_Bool ewk_frame_mixed_content_run_get(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    return smartData->hasRunMixedContent;
}

Ewk_Certificate_Status ewk_frame_certificate_status_get(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EWK_CERTIFICATE_STATUS_NO_CERTIFICATE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EWK_CERTIFICATE_STATUS_NO_CERTIFICATE);

    const WebCore::FrameLoader* frameLoader = smartData->frame->loader();
    const WebCore::DocumentLoader* documentLoader = frameLoader->documentLoader();
    const WebCore::KURL documentURL = documentLoader->requestURL();

    if (!documentURL.protocolIs("https"))
        return EWK_CERTIFICATE_STATUS_NO_CERTIFICATE;

    if (frameLoader->subframeIsLoading())
        return EWK_CERTIFICATE_STATUS_NO_CERTIFICATE;

    SoupMessage* soupMessage = documentLoader->request().toSoupMessage();

    if (soupMessage && (soup_message_get_flags(soupMessage) & SOUP_MESSAGE_CERTIFICATE_TRUSTED))
        return EWK_CERTIFICATE_STATUS_TRUSTED;

    return EWK_CERTIFICATE_STATUS_UNTRUSTED;
}

/**
 * @internal
 * Reports frame favicon changed.
 *
 * @param ewkFrame Frame.
 *
 * Emits signal: "icon,changed" with no parameters.
 */
void ewk_frame_icon_changed(Evas_Object* ewkFrame)
{
    DBG("ewkFrame=%p", ewkFrame);
    evas_object_smart_callback_call(ewkFrame, "icon,changed", 0);
}

/**
 * @internal
 * Reports uri changed and swap internal string reference.
 *
 * Emits signal: "uri,changed" with new uri as parameter.
 */
bool ewk_frame_uri_changed(Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
    WTF::CString uri(smartData->frame->document()->url().string().utf8());

    INFO("uri=%s", uri.data());
    if (!uri.data()) {
        ERR("no uri");
        return false;
    }

    eina_stringshare_replace(&smartData->uri, uri.data());
    evas_object_smart_callback_call(ewkFrame, "uri,changed", (void*)smartData->uri);
    return true;
}

/**
 * @internal
 *
 * Forces layout for frame.
 */
void ewk_frame_force_layout(Evas_Object* ewkFrame)
{
    DBG("ewkFrame=%p", ewkFrame);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
    WebCore::FrameView* view = smartData->frame->view();
    if (view)
        view->forceLayout(true);
}

/**
 * @internal
 *
 * Creates plugin.
 */
WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* ewkFrame, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::KURL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually)
{
#if ENABLE(NETSCAPE_PLUGIN_API)
    DBG("ewkFrame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
        ewkFrame, pluginSize.width(), pluginSize.height(), element,
        url.string().utf8().data(), mimeType.utf8().data());

    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, 0);

    // TODO: emit signal and ask webkit users if something else should be done.
    // like creating another x window (see gtk, it allows users to create
    // GtkPluginWidget.

    WTF::RefPtr<WebCore::PluginView> pluginView = WebCore::PluginView::create
        (sd->frame, pluginSize, element, url, paramNames, paramValues,
        mimeType, loadManually);

    if (pluginView->status() == WebCore::PluginStatusLoadedSuccessfully)
        return pluginView.release();
#else
    UNUSED_PARAM(ewkFrame);
    UNUSED_PARAM(pluginSize);
    UNUSED_PARAM(element);
    UNUSED_PARAM(url);
    UNUSED_PARAM(paramNames);
    UNUSED_PARAM(paramValues);
    UNUSED_PARAM(mimeType);
    UNUSED_PARAM(loadManually);
#endif // #if ENABLE(NETSCAPE_PLUGIN_API)
    return 0;
}

/**
 * @internal
 * Reports that editor client selection was changed.
 *
 * @param ewkFrame Frame
 *
 * Emits signal: "editorclientselection,changed" with no parameters.
 */
void ewk_frame_editor_client_selection_changed(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "editorclient,selection,changed", 0);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_editor_client_selection_changed(smartData->view);
}

/**
 * @internal
 * Reports that editor client's contents were changed.
 *
 * @param o Frame
 *
 * Emits signal: "editorclient,contents,changed" with no parameters.
 */
void ewk_frame_editor_client_contents_changed(Evas_Object* ewkFrame)
{
    evas_object_smart_callback_call(ewkFrame, "editorclient,contents,changed", 0);
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    ewk_view_editor_client_contents_changed(smartData->view);
}

/**
 * @internal
 * Defines whether the frame has displayed mixed content.
 *
 * When a frame has displayed mixed content, the currently loaded URI is secure (HTTPS) but it has
 * loaded and displayed a resource, such as an image, from an insecure (HTTP) source.
 *
 * @param hasDisplayed Do or do not clear the flag from the frame. If @c true, the container view
 *                     is also notified and it then emits the "mixedcontent,displayed" signal.
 *
 * Emits signal: "mixedcontent,displayed" with no parameters when @p hasDisplayed is @c true.
 */
void ewk_frame_mixed_content_displayed_set(Evas_Object* ewkFrame, bool hasDisplayed)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    smartData->hasDisplayedMixedContent = hasDisplayed;

    if (hasDisplayed) {
        ewk_view_mixed_content_displayed_set(smartData->view, true);
        evas_object_smart_callback_call(ewkFrame, "mixedcontent,displayed", 0);
    }
}

/**
 * @internal
 * Defines whether the frame has run mixed content.
 *
 * When a frame has run mixed content, the currently loaded URI is secure (HTTPS) but it has
 * loaded and run a resource, such as a script, from an insecure (HTTP) source.
 *
 * @param hasDisplayed Do or do not clear the flag from the frame. If @c true, the container view
 *                     is also notified and it then emits the "mixedcontent,run" signal.
 *
 * Emits signal: "mixedcontent,run" with no parameters when @p hasRun is @c true.
 */
void ewk_frame_mixed_content_run_set(Evas_Object* ewkFrame, bool hasRun)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
    smartData->hasRunMixedContent = hasRun;

    if (hasRun) {
        ewk_view_mixed_content_run_set(smartData->view, true);
        evas_object_smart_callback_call(ewkFrame, "mixedcontent,run", 0);
    }
}

/**
 * @internal
 * Reports that reflected XSS is encountered in the page and suppressed.
 *
 * @param xssInfo Information received from the XSSAuditor when XSS is 
 * encountered in the page. 
 *
 * Emits signal: "xss,detected" with pointer to Ewk_Frame_Xss_Notification.
 */
void ewk_frame_xss_detected(Evas_Object* ewkFrame, const Ewk_Frame_Xss_Notification* xssInfo)
{
    evas_object_smart_callback_call(ewkFrame, "xss,detected", (void*)xssInfo);
}

namespace EWKPrivate {

WebCore::Frame* coreFrame(const Evas_Object* ewkFrame)
{
    EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
    return smartData->frame;
}

Evas_Object* kitFrame(const WebCore::Frame* coreFrame)
{
    if (!coreFrame)
        return 0;

    WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(coreFrame);
    if (!frameLoaderClient)
        return 0;

    return frameLoaderClient->webFrame();
}

} // namespace EWKPrivate
