/*
    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
