blob: 4a8aaf3384786cde61149103f80443c0f1a22365 [file] [log] [blame]
/*
Copyright (C) 2009-2010 ProFUSION embedded systems
Copyright (C) 2009-2012 Samsung Electronics
Copyright (C) 2012 Intel Corporation
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.
*/
#define __STDC_FORMAT_MACROS
#include "config.h"
#include "ewk_view.h"
#include "BackForwardListImpl.h"
#include "Bridge.h"
#include "Chrome.h"
#include "ChromeClientEfl.h"
#include "ContextMenuClientEfl.h"
#include "ContextMenuController.h"
#include "DocumentLoader.h"
#include "DragClientEfl.h"
#include "DumpRenderTreeSupportEfl.h"
#include "Editor.h"
#include "EditorClientEfl.h"
#include "EflScreenUtilities.h"
#include "EventHandler.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoaderClientEfl.h"
#include "FrameSelection.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "InspectorClientEfl.h"
#include "InspectorController.h"
#include "IntSize.h"
#include "JSDOMBinding.h"
#include "JSDOMWindow.h"
#include "JSLock.h"
#include "NetworkStorageSession.h"
#include "Operations.h"
#include "PageClientEfl.h"
#include "PageGroup.h"
#include "PlatformMouseEvent.h"
#include "PopupMenuClient.h"
#include "ProgressTracker.h"
#include "RefPtrCairo.h"
#include "RenderThemeEfl.h"
#include "ResourceHandle.h"
#include "RuntimeEnabledFeatures.h"
#include "ScriptController.h"
#include "Settings.h"
#include "TiledBackingStore.h"
#include "c_instance.h"
#include "ewk_contextmenu_private.h"
#include "ewk_frame.h"
#include "ewk_frame_private.h"
#include "ewk_history_private.h"
#include "ewk_js_private.h"
#include "ewk_paint_context_private.h"
#include "ewk_private.h"
#include "ewk_settings_private.h"
#include "ewk_view_private.h"
#include "ewk_window_features_private.h"
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Edje.h>
#include <Eina.h>
#include <Evas.h>
#include <eina_safety_checks.h>
#include <inttypes.h>
#include <libsoup/soup.h>
#include <limits>
#include <math.h>
#include <sys/time.h>
#if ENABLE(DEVICE_ORIENTATION)
#include "DeviceMotionClientEfl.h"
#include "DeviceOrientationClientEfl.h"
#endif
#if ENABLE(GEOLOCATION)
#include "GeolocationClientMock.h"
#include "GeolocationController.h"
#endif
#if ENABLE(VIBRATION)
#include "VibrationClientEfl.h"
#endif
#if ENABLE(BATTERY_STATUS)
#include "BatteryClientEfl.h"
#endif
#if USE(ACCELERATED_COMPOSITING)
#include "AcceleratedCompositingContextEfl.h"
#endif
#if ENABLE(NETWORK_INFO)
#include "NetworkInfoClientEfl.h"
#endif
#if ENABLE(INPUT_TYPE_COLOR)
#include "ColorChooserClient.h"
#endif
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
#include "NavigatorContentUtilsClientEfl.h"
#endif
static const float zoomMinimum = 0.05;
static const float zoomMaximum = 4.0;
static const float devicePixelRatio = 1.0;
static const char ewkViewTypeString[] = "EWK_View";
static const size_t ewkViewRepaintsSizeInitial = 32;
static const size_t ewkViewRepaintsSizeStep = 8;
static const size_t ewkViewRepaintsSizeMaximumFree = 64;
static const size_t ewkViewScrollsSizeInitial = 8;
static const size_t ewkViewScrollsSizeStep = 2;
static const size_t ewkViewScrollsSizeMaximumFree = 32;
static const Evas_Smart_Cb_Description _ewk_view_callback_names[] = {
{ "colorchooser,create", "(yyyy)" },
{ "colorchooser,willdelete", "" },
{ "colorchooser,color,changed", "(yyyy)" },
{ "download,request", "p" },
{ "editorclient,contents,changed", "" },
{ "editorclient,selection,changed", "" },
{ "frame,created", "p" },
{ "icon,received", "" },
{ "inputmethod,changed", "b" },
{ "js,windowobject,clear", "" },
{ "link,hover,in", "p" },
{ "link,hover,out", "" },
{ "load,document,finished", "p" },
{ "load,error", "p" },
{ "load,finished", "p" },
{ "load,newwindow,show", "" },
{ "load,progress", "d" },
{ "load,provisional", "" },
{ "load,started", "" },
{ "menubar,visible,get", "b" },
{ "menubar,visible,set", "b" },
{ "popup,created", "p" },
{ "popup,willdelete", "p" },
{ "ready", "" },
{ "scrollbars,visible,get", "b" },
{ "scrollbars,visible,set", "b" },
{ "statusbar,text,set", "s" },
{ "statusbar,visible,get", "b" },
{ "statusbar,visible,set", "b" },
{ "title,changed", "s" },
{ "toolbars,visible,get", "b" },
{ "toolbars,visible,set", "b" },
{ "tooltip,text,set", "s" },
{ "tooltip,text,unset", "s" },
{ "uri,changed", "s" },
{ "view,resized", "" },
{ "zoom,animated,end", "" },
{ 0, 0 }
};
struct EditorCommand {
Ewk_Editor_Command ewkEditorCommand;
const char* editorCommandString;
};
/**
* @brief A table grouping Ewk_Editor_Command enums with corresponding command
* strings used by WebCore::EditorCommand, keeping both in sync.
*
* @internal
*/
static const EditorCommand editorCommands[] = {
{ EWK_EDITOR_COMMAND_UNDO, "Undo" },
{ EWK_EDITOR_COMMAND_REDO, "Redo" },
{ EWK_EDITOR_COMMAND_TOGGLE_BOLD, "ToggleBold" },
{ EWK_EDITOR_COMMAND_TOGGLE_ITALIC, "ToggleItalic" },
{ EWK_EDITOR_COMMAND_TOGGLE_UNDERLINE, "ToggleUnderline" },
{ EWK_EDITOR_COMMAND_TOGGLE_STRIKETHROUGH, "Strikethrough" },
{ EWK_EDITOR_COMMAND_TOGGLE_SUBSCRIPT, "SubScript" },
{ EWK_EDITOR_COMMAND_TOGGLE_SUPERSCRIPT, "SuperScript" },
{ EWK_EDITOR_COMMAND_INDENT, "Indent" },
{ EWK_EDITOR_COMMAND_OUTDENT, "Outdent" },
{ EWK_EDITOR_COMMAND_INSERT_ORDEREDLIST, "InsertOrderedList" },
{ EWK_EDITOR_COMMAND_INSERT_UNORDEREDLIST, "InsertUnorderedList" },
{ EWK_EDITOR_COMMAND_INSERT_IMAGE, "InsertImage" },
{ EWK_EDITOR_COMMAND_INSERT_TEXT, "InsertText" },
{ EWK_EDITOR_COMMAND_INSERT_HTML, "InsertHTML" },
{ EWK_EDITOR_COMMAND_INSERT_PARAGRAPH, "InsertParagraph" },
{ EWK_EDITOR_COMMAND_INSERT_PARAGRAPH_SEPARATOR, "InsertNewLine" },
{ EWK_EDITOR_COMMAND_INSERT_LINE_SEPARATOR, "InsertLineBreak" },
{ EWK_EDITOR_COMMAND_BACK_COLOR, "BackColor" },
{ EWK_EDITOR_COMMAND_FORE_COLOR, "ForeColor" },
{ EWK_EDITOR_COMMAND_HILITE_COLOR, "HiliteColor" },
{ EWK_EDITOR_COMMAND_FONT_SIZE, "FontSize" },
{ EWK_EDITOR_COMMAND_ALIGN_CENTER, "AlignCenter" },
{ EWK_EDITOR_COMMAND_ALIGN_JUSTIFIED, "AlignJustified" },
{ EWK_EDITOR_COMMAND_ALIGN_LEFT, "AlignLeft" },
{ EWK_EDITOR_COMMAND_ALIGN_RIGHT, "AlignRight" },
{ EWK_EDITOR_COMMAND_MOVE_TO_NEXT_CHAR, "MoveForward" },
{ EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_CHAR, "MoveBackward" },
{ EWK_EDITOR_COMMAND_MOVE_TO_NEXT_WORD, "MoveWordForward" },
{ EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_WORD, "MoveWordBackward" },
{ EWK_EDITOR_COMMAND_MOVE_TO_NEXT_LINE, "MoveDown" },
{ EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_LINE, "MoveUp" },
{ EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_LINE, "MoveToBeginningOfLine" },
{ EWK_EDITOR_COMMAND_MOVE_TO_END_OF_LINE, "MoveToEndOfLine" },
{ EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_PARAGRAPH, "MoveToBeginningOfParagraph" },
{ EWK_EDITOR_COMMAND_MOVE_TO_END_OF_PARAGRAPH, "MoveToEndOfParagraph" },
{ EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_DOCUMENT, "MoveToBeginningOfDocument" },
{ EWK_EDITOR_COMMAND_MOVE_TO_END_OF_DOCUMENT, "MoveToEndOfDocument" },
{ EWK_EDITOR_COMMAND_SELECT_NONE, "SelectNone" },
{ EWK_EDITOR_COMMAND_SELECT_ALL, "SelectAll" },
{ EWK_EDITOR_COMMAND_SELECT_PARAGRAPH, "SelectParagraph" },
{ EWK_EDITOR_COMMAND_SELECT_SENTENCE, "SelectSentence" },
{ EWK_EDITOR_COMMAND_SELECT_LINE, "SelectLine" },
{ EWK_EDITOR_COMMAND_SELECT_WORD, "SelectWord" },
{ EWK_EDITOR_COMMAND_SELECT_NEXT_CHAR, "MoveForwardAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_PREVIOUS_CHAR, "MoveBackwardAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_NEXT_WORD, "MoveWordForwardAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_PREVIOUS_WORD, "MoveWordBackwardAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_NEXT_LINE, "MoveDownAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_PREVIOUS_LINE, "MoveUpAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_START_OF_LINE, "MoveToBeginningOfLineAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_END_OF_LINE, "MoveToEndOfLineAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_START_OF_PARAGRAPH, "MoveToBeginningOfParagraphAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_END_OF_PARAGRAPH, "MoveToEndOfParagraphAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_START_OF_DOCUMENT, "MoveToBeginningOfDocumentAndModifySelection" },
{ EWK_EDITOR_COMMAND_SELECT_END_OF_DOCUMENT, "MoveToEndOfDocumentAndModifySelection" },
{ EWK_EDITOR_COMMAND_DELETE_WORD_BACKWARD, "DeleteWordBackward" },
{ EWK_EDITOR_COMMAND_DELETE_WORD_FORWARD, "DeleteWordForward" },
{ EWK_EDITOR_COMMAND_NONE, 0 } // EWK_EDITOR_COMMAND_NONE must be the last element.
};
/**
* @brief Private data that is used internally by EFL WebKit
* and should never be modified from outside.
*
* @internal
*/
struct _Ewk_View_Private_Data {
OwnPtr<WebCore::Page> page;
WebCore::Settings* pageSettings;
WebCore::Frame* mainFrame;
WebCore::ViewportArguments viewportArguments;
Ewk_History* history;
OwnPtr<PageClientEfl> pageClient;
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<WebCore::AcceleratedCompositingContext> acceleratedCompositingContext;
bool isCompositingActive;
RefPtr<Evas_Object> compositingObject;
#endif
#if ENABLE(INPUT_TYPE_COLOR)
WebCore::ColorChooserClient* colorChooserClient;
#endif
#if ENABLE(NAVIGATOR_CONTENT_UTILS) || ENABLE(CUSTOM_SCHEME_HANDLER)
OwnPtr<WebCore::NavigatorContentUtilsClientEfl> navigatorContentUtilsClient;
#endif
OwnPtr<WebCore::NetworkStorageSession> storageSession;
struct {
Ewk_Menu menu;
WebCore::PopupMenuClient* menuClient;
} popup;
struct {
Eina_Rectangle* array;
size_t count;
size_t allocated;
} repaints;
struct {
Ewk_Scroll_Request* array;
size_t count;
size_t allocated;
} scrolls;
unsigned int imh; /**< input method hints */
struct {
bool viewCleared : 1;
bool needTouchEvents : 1;
bool hasDisplayedMixedContent : 1;
bool hasRunMixedContent : 1;
} flags;
struct {
const char* userAgent;
const char* userStylesheet;
const char* encodingDefault;
const char* encodingCustom;
const char* theme;
const char* localStorageDatabasePath;
int fontMinimumSize;
int fontMinimumLogicalSize;
int fontDefaultSize;
int fontMonospaceSize;
const char* fontStandard;
const char* fontCursive;
const char* fontMonospace;
const char* fontFantasy;
const char* fontSerif;
const char* fontSansSerif;
bool autoLoadImages : 1;
bool autoShrinkImages : 1;
bool enableAutoResizeWindow : 1;
bool enableDeveloperExtras : 1;
bool enableScripts : 1;
bool enablePlugins : 1;
bool enableFrameFlattening : 1;
#if ENABLE(FULLSCREEN_API)
bool enableFullscreen : 1;
#endif
bool encodingDetector : 1;
bool hyperlinkAuditingEnabled : 1;
bool scriptsCanOpenWindows : 1;
bool scriptsCanCloseWindows : 1;
#if ENABLE(VIDEO_TRACK)
bool shouldDisplayCaptions : 1;
bool shouldDisplaySubtitles : 1;
bool shouldDisplayTextDescriptions: 1;
#endif
bool scriptsCanAccessClipboard : 1;
bool resizableTextareas : 1;
bool privateBrowsing : 1;
bool caretBrowsing : 1;
bool spatialNavigation : 1;
bool localStorage : 1;
bool offlineAppCache : 1;
bool pageCache : 1;
bool enableXSSAuditor : 1;
#if ENABLE(WEB_AUDIO)
bool webAudio : 1;
#endif
bool webGLEnabled : 1;
bool tabsToLinks : 1;
struct {
float minScale;
float maxScale;
Eina_Bool userScalable : 1;
} zoomRange;
float devicePixelRatio;
double domTimerInterval;
bool allowUniversalAccessFromFileURLs : 1;
bool allowFileAccessFromFileURLs : 1;
} settings;
struct {
struct {
double start;
double end;
double duration;
} time;
struct {
float start;
float end;
float range;
} zoom;
struct {
Evas_Coord x, y;
} center;
Ecore_Animator* animator;
} animatedZoom;
const char* cursorGroup;
Evas_Object* cursorObject;
#if ENABLE(INSPECTOR)
Evas_Object* inspectorView;
#endif
#ifdef HAVE_ECORE_X
bool isUsingEcoreX;
#endif
#if ENABLE(CONTEXT_MENUS)
Ewk_Context_Menu* contextMenu;
#endif
};
#ifndef EWK_TYPE_CHECK
#define EWK_VIEW_TYPE_CHECK(ewkView, ...) do { } while (0)
#else
#define EWK_VIEW_TYPE_CHECK(ewkView, ...) \
do { \
const char* _tmp_otype = evas_object_type_get(ewkView); \
const Evas_Smart* _tmp_s = evas_object_smart_smart_get(ewkView); \
if (EINA_UNLIKELY(!_tmp_s)) { \
EINA_LOG_CRIT \
("%p (%s) is not a smart object!", ewkView, \
_tmp_otype ? _tmp_otype : "(null)"); \
return __VA_ARGS__; \
} \
const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \
if (EINA_UNLIKELY(!_tmp_sc)) { \
EINA_LOG_CRIT \
("%p (%s) is not a smart object!", ewkView, \
_tmp_otype ? _tmp_otype : "(null)"); \
return __VA_ARGS__; \
} \
if (EINA_UNLIKELY(_tmp_sc->data != ewkViewTypeString)) { \
EINA_LOG_CRIT \
("%p (%s) is not of an ewk_view (need %p, got %p)!", \
ewkView, _tmp_otype ? _tmp_otype : "(null)", \
ewkViewTypeString, _tmp_sc->data); \
return __VA_ARGS__; \
} \
} while (0)
#endif
#define EWK_VIEW_SD_GET(ewkView, pointer) \
Ewk_View_Smart_Data* pointer = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(ewkView))
#define EWK_VIEW_SD_GET_OR_RETURN(ewkView, pointer, ...) \
EWK_VIEW_TYPE_CHECK(ewkView, __VA_ARGS__); \
EWK_VIEW_SD_GET(ewkView, pointer); \
if (!pointer) { \
CRITICAL("no smart data for object %p (%s)", \
ewkView, evas_object_type_get(ewkView)); \
return __VA_ARGS__; \
}
#define EWK_VIEW_PRIV_GET(smartData, pointer) \
Ewk_View_Private_Data* pointer = smartData->_priv
#define EWK_VIEW_PRIV_GET_OR_RETURN(smartData, pointer, ...) \
EWK_VIEW_PRIV_GET(smartData, pointer); \
if (!pointer) { \
CRITICAL("no private data for object %p (%s)", \
smartData->self, evas_object_type_get(smartData->self)); \
return __VA_ARGS__; \
}
static void _ewk_view_smart_changed(Ewk_View_Smart_Data* smartData)
{
if (smartData->changed.any)
return;
smartData->changed.any = true;
evas_object_smart_changed(smartData->self);
}
static Eina_Bool _ewk_view_repaints_resize(Ewk_View_Private_Data* priv, size_t size)
{
void* tmp = realloc(priv->repaints.array, size * sizeof(Eina_Rectangle));
if (!tmp) {
CRITICAL("could not realloc repaints array to %zu elements.", size);
return false;
}
priv->repaints.allocated = size;
priv->repaints.array = static_cast<Eina_Rectangle*>(tmp);
return true;
}
static void _ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
{
size_t newSize = 0;
if (priv->repaints.allocated == priv->repaints.count)
newSize = priv->repaints.allocated + ewkViewRepaintsSizeStep;
else if (!priv->repaints.count && priv->repaints.allocated > ewkViewRepaintsSizeInitial)
newSize = ewkViewRepaintsSizeInitial;
if (newSize) {
if (!_ewk_view_repaints_resize(priv, newSize))
return;
}
Eina_Rectangle* rect = priv->repaints.array + priv->repaints.count;
priv->repaints.count++;
rect->x = x;
rect->y = y;
rect->w = width;
rect->h = height;
DBG("add repaint %d, %d+%dx%d", x, y, width, height);
}
static void _ewk_view_repaints_flush(Ewk_View_Private_Data* priv)
{
priv->repaints.count = 0;
if (priv->repaints.allocated <= ewkViewRepaintsSizeMaximumFree)
return;
_ewk_view_repaints_resize(priv, ewkViewRepaintsSizeMaximumFree);
}
static Eina_Bool _ewk_view_scrolls_resize(Ewk_View_Private_Data* priv, size_t size)
{
void* tmp = realloc(priv->scrolls.array, size * sizeof(Ewk_Scroll_Request));
if (!tmp) {
CRITICAL("could not realloc scrolls array to %zu elements.", size);
return false;
}
priv->scrolls.allocated = size;
priv->scrolls.array = static_cast<Ewk_Scroll_Request*>(tmp);
return true;
}
static void _ewk_view_scroll_add(Ewk_View_Private_Data* priv, Evas_Coord deltaX, Evas_Coord deltaY, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
{
Ewk_Scroll_Request* rect;
Ewk_Scroll_Request* rect_end;
Evas_Coord x2 = x + width, y2 = y + height;
rect = priv->scrolls.array;
rect_end = rect + priv->scrolls.count;
for (; rect < rect_end; rect++) {
if (rect->x == x && rect->y == y && rect->w == width && rect->h == height) {
DBG("region already scrolled %d,%d+%dx%d %+03d,%+03d add "
"%+03d,%+03d",
rect->x, rect->y, rect->w, rect->h, rect->dx, rect->dy, deltaX, deltaY);
rect->dx += deltaX;
rect->dy += deltaY;
return;
}
if ((x <= rect->x && x2 >= rect->x2) && (y <= rect->y && y2 >= rect->y2)) {
DBG("old viewport (%d,%d+%dx%d %+03d,%+03d) was scrolled itself, "
"add %+03d,%+03d",
rect->x, rect->y, rect->w, rect->h, rect->dx, rect->dy, deltaX, deltaY);
rect->x += deltaX;
rect->y += deltaY;
}
}
if (priv->scrolls.allocated == priv->scrolls.count) {
size_t size;
if (!priv->scrolls.allocated)
size = ewkViewScrollsSizeInitial;
else
size = priv->scrolls.allocated + ewkViewScrollsSizeStep;
if (!_ewk_view_scrolls_resize(priv, size))
return;
}
rect = priv->scrolls.array + priv->scrolls.count;
priv->scrolls.count++;
rect->x = x;
rect->y = y;
rect->w = width;
rect->h = height;
rect->x2 = x2;
rect->y2 = y2;
rect->dx = deltaX;
rect->dy = deltaY;
DBG("add scroll in region: %d, %d+%dx%d %+03d, %+03d", x, y, width, height, deltaX, deltaY);
Eina_Rectangle* pr;
Eina_Rectangle* pr_end;
size_t count;
pr = priv->repaints.array;
count = priv->repaints.count;
pr_end = pr + count;
for (; pr < pr_end; pr++) {
pr->x += deltaX;
pr->y += deltaY;
}
}
static void _ewk_view_scrolls_flush(Ewk_View_Private_Data* priv)
{
priv->scrolls.count = 0;
if (priv->scrolls.allocated <= ewkViewScrollsSizeMaximumFree)
return;
_ewk_view_scrolls_resize(priv, ewkViewScrollsSizeMaximumFree);
}
// Default Event Handling //////////////////////////////////////////////
static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
{
EWK_VIEW_PRIV_GET(smartData, priv);
WebCore::FocusController* focusController = priv->page->focusController();
DBG("ewkView=%p, focusController=%p", smartData->self, focusController);
EINA_SAFETY_ON_NULL_RETURN_VAL(focusController, false);
focusController->setActive(true);
focusController->setFocused(true);
return true;
}
static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* smartData)
{
EWK_VIEW_PRIV_GET(smartData, priv);
WebCore::FocusController* focusController = priv->page->focusController();
DBG("ewkView=%p, fc=%p", smartData->self, focusController);
EINA_SAFETY_ON_NULL_RETURN_VAL(focusController, false);
focusController->setActive(false);
focusController->setFocused(false);
return true;
}
static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
{
return ewk_frame_feed_mouse_wheel(smartData->main_frame, wheelEvent);
}
static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
{
return ewk_frame_feed_mouse_down(smartData->main_frame, downEvent);
}
static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
{
return ewk_frame_feed_mouse_up(smartData->main_frame, upEvent);
}
static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
{
return ewk_frame_feed_mouse_move(smartData->main_frame, moveEvent);
}
static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
{
Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
if (!frame)
frame = smartData->main_frame;
return ewk_frame_feed_key_down(frame, downEvent);
}
static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
{
Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
if (!frame)
frame = smartData->main_frame;
return ewk_frame_feed_key_up(frame, upEvent);
}
static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data*, const char* message, unsigned int lineNumber, const char* sourceID)
{
INFO("console message: %s @%d: %s\n", sourceID, lineNumber, message);
}
static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message)
{
INFO("javascript alert: %s\n", message);
}
static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message)
{
INFO("javascript confirm: %s", message);
INFO("javascript confirm (HARD CODED)? YES");
return true;
}
static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data*)
{
INFO("should interrupt javascript?\n"
"\t(HARD CODED) NO");
return false;
}
static Eina_Bool _ewk_view_smart_run_javascript_prompt(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message, const char* defaultValue, const char** value)
{
*value = eina_stringshare_add("test");
Eina_Bool result = true;
INFO("javascript prompt:\n"
"\t message: %s\n"
"\tdefault value: %s\n"
"\tgiving answer: %s\n"
"\t button: %s", message, defaultValue, *value, result ? "ok" : "cancel");
return result;
}
// Event Handling //////////////////////////////////////////////////////
static void _ewk_view_on_focus_in(void* data, Evas*, Evas_Object*, void*)
{
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_in);
smartData->api->focus_in(smartData);
}
static void _ewk_view_on_focus_out(void* data, Evas*, Evas_Object*, void*)
{
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_out);
smartData->api->focus_out(smartData);
}
static void _ewk_view_on_mouse_wheel(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Mouse_Wheel* wheelEvent = static_cast<Evas_Event_Mouse_Wheel*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_wheel);
smartData->api->mouse_wheel(smartData, wheelEvent);
}
static void _ewk_view_on_mouse_down(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_down);
smartData->api->mouse_down(smartData, downEvent);
}
static void _ewk_view_on_mouse_up(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_up);
smartData->api->mouse_up(smartData, upEvent);
}
static void _ewk_view_on_mouse_move(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_move);
smartData->api->mouse_move(smartData, moveEvent);
}
static void _ewk_view_on_key_down(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Key_Down* downEvent = static_cast<Evas_Event_Key_Down*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_down);
smartData->api->key_down(smartData, downEvent);
}
static void _ewk_view_on_key_up(void* data, Evas*, Evas_Object*, void* eventInfo)
{
Evas_Event_Key_Up* upEvent = static_cast<Evas_Event_Key_Up*>(eventInfo);
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_up);
smartData->api->key_up(smartData, upEvent);
}
static WTF::PassRefPtr<WebCore::Frame> _ewk_view_core_frame_new(Ewk_View_Smart_Data* smartData, Ewk_View_Private_Data* priv, WebCore::HTMLFrameOwnerElement* owner)
{
WebCore::FrameLoaderClientEfl* frameLoaderClient = new WebCore::FrameLoaderClientEfl(smartData->self);
frameLoaderClient->setCustomUserAgent(String::fromUTF8(priv->settings.userAgent));
return WebCore::Frame::create(priv->page.get(), owner, frameLoaderClient);
}
static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData)
{
Ewk_View_Private_Data* priv = new Ewk_View_Private_Data;
memset(priv, 0, sizeof(Ewk_View_Private_Data));
AtomicString string;
WebCore::KURL url;
WebCore::Page::PageClients pageClients;
pageClients.chromeClient = new WebCore::ChromeClientEfl(smartData->self);
#if ENABLE(CONTEXT_MENUS)
pageClients.contextMenuClient = new WebCore::ContextMenuClientEfl;
#endif
pageClients.editorClient = new WebCore::EditorClientEfl(smartData->self);
pageClients.dragClient = new WebCore::DragClientEfl;
#if ENABLE(INSPECTOR)
pageClients.inspectorClient = new WebCore::InspectorClientEfl(smartData->self);
#endif
priv->page = adoptPtr(new WebCore::Page(pageClients));
#if ENABLE(DEVICE_ORIENTATION)
WebCore::provideDeviceMotionTo(priv->page.get(), new WebCore::DeviceMotionClientEfl);
WebCore::provideDeviceOrientationTo(priv->page.get(), new WebCore::DeviceOrientationClientEfl);
#endif
#if ENABLE(NETWORK_INFO)
WebCore::provideNetworkInfoTo(priv->page.get(), new WebCore::NetworkInfoClientEfl);
#endif
#if ENABLE(VIBRATION)
WebCore::provideVibrationTo(priv->page.get(), new WebCore::VibrationClientEfl(smartData->self));
#endif
#if ENABLE(BATTERY_STATUS)
WebCore::provideBatteryTo(priv->page.get(), new BatteryClientEfl(smartData->self));
#endif
#if ENABLE(NAVIGATOR_CONTENT_UTILS)
priv->navigatorContentUtilsClient = WebCore::NavigatorContentUtilsClientEfl::create(smartData->self);
WebCore::provideNavigatorContentUtilsTo(priv->page.get(), priv->navigatorContentUtilsClient.get());
#endif
#if ENABLE(GEOLOCATION)
if (DumpRenderTreeSupportEfl::dumpRenderTreeModeEnabled()) {
WebCore::GeolocationClientMock* mock = new WebCore::GeolocationClientMock;
WebCore::provideGeolocationTo(priv->page.get(), mock);
mock->setController(WebCore::GeolocationController::from(priv->page.get()));
}
#endif
priv->pageSettings = priv->page->settings();
WebCore::LayoutMilestones layoutMilestones = WebCore::DidFirstLayout | WebCore::DidFirstVisuallyNonEmptyLayout;
priv->page->addLayoutMilestones(layoutMilestones);
// FIXME: Noone is supposed to do this manually.
priv->viewportArguments.width = WebCore::ViewportArguments::ValueAuto;
priv->viewportArguments.height = WebCore::ViewportArguments::ValueAuto;
priv->viewportArguments.zoom = WebCore::ViewportArguments::ValueAuto;
priv->viewportArguments.minZoom = WebCore::ViewportArguments::ValueAuto;
priv->viewportArguments.maxZoom = WebCore::ViewportArguments::ValueAuto;
priv->viewportArguments.userZoom = true;
priv->pageSettings->setLoadsImagesAutomatically(true);
priv->pageSettings->setDefaultTextEncodingName("iso-8859-1");
priv->pageSettings->setDefaultFixedFontSize(12);
priv->pageSettings->setDefaultFontSize(16);
priv->pageSettings->setSerifFontFamily("serif");
priv->pageSettings->setFixedFontFamily("monotype");
priv->pageSettings->setSansSerifFontFamily("sans");
priv->pageSettings->setStandardFontFamily("sans");
priv->pageSettings->setHyperlinkAuditingEnabled(false);
WebCore::RuntimeEnabledFeatures::setCSSRegionsEnabled(true);
#if ENABLE(IFRAME_SEAMLESS)
WebCore::RuntimeEnabledFeatures::setSeamlessIFramesEnabled(true);
#endif
priv->pageSettings->setScriptEnabled(true);
priv->pageSettings->setPluginsEnabled(true);
priv->pageSettings->setLocalStorageEnabled(true);
priv->pageSettings->setOfflineWebApplicationCacheEnabled(true);
priv->pageSettings->setUsesPageCache(true);
priv->pageSettings->setUsesEncodingDetector(false);
#if ENABLE(WEB_AUDIO)
priv->pageSettings->setWebAudioEnabled(false);
#endif
priv->pageSettings->setWebGLEnabled(true);
priv->pageSettings->setXSSAuditorEnabled(true);
#if ENABLE(FULLSCREEN_API)
priv->pageSettings->setFullScreenEnabled(true);
#endif
priv->pageSettings->setInteractiveFormValidationEnabled(true);
#if USE(ACCELERATED_COMPOSITING)
priv->pageSettings->setAcceleratedCompositingEnabled(false);
char* debugVisualsEnvironment = getenv("WEBKIT_SHOW_COMPOSITING_DEBUG_VISUALS");
bool showDebugVisuals = debugVisualsEnvironment && !strcmp(debugVisualsEnvironment, "1");
priv->pageSettings->setShowDebugBorders(showDebugVisuals);
priv->pageSettings->setShowRepaintCounter(showDebugVisuals);
#endif
url = priv->pageSettings->userStyleSheetLocation();
priv->settings.userStylesheet = eina_stringshare_add(url.string().utf8().data());
priv->settings.encodingDefault = eina_stringshare_add
(priv->pageSettings->defaultTextEncodingName().utf8().data());
priv->settings.encodingCustom = 0;
string = priv->pageSettings->localStorageDatabasePath();
priv->settings.localStorageDatabasePath = eina_stringshare_add(string.string().utf8().data());
priv->settings.fontMinimumSize = priv->pageSettings->minimumFontSize();
priv->settings.fontMinimumLogicalSize = priv->pageSettings->minimumLogicalFontSize();
priv->settings.fontDefaultSize = priv->pageSettings->defaultFontSize();
priv->settings.fontMonospaceSize = priv->pageSettings->defaultFixedFontSize();
string = priv->pageSettings->standardFontFamily();
priv->settings.fontStandard = eina_stringshare_add(string.string().utf8().data());
string = priv->pageSettings->cursiveFontFamily();
priv->settings.fontCursive = eina_stringshare_add(string.string().utf8().data());
string = priv->pageSettings->fixedFontFamily();
priv->settings.fontMonospace = eina_stringshare_add(string.string().utf8().data());
string = priv->pageSettings->fantasyFontFamily();
priv->settings.fontFantasy = eina_stringshare_add(string.string().utf8().data());
string = priv->pageSettings->serifFontFamily();
priv->settings.fontSerif = eina_stringshare_add(string.string().utf8().data());
string = priv->pageSettings->sansSerifFontFamily();
priv->settings.fontSansSerif = eina_stringshare_add(string.string().utf8().data());
priv->settings.autoLoadImages = priv->pageSettings->loadsImagesAutomatically();
priv->settings.autoShrinkImages = priv->pageSettings->shrinksStandaloneImagesToFit();
priv->settings.enableAutoResizeWindow = true;
priv->settings.enableDeveloperExtras = priv->pageSettings->developerExtrasEnabled();
priv->settings.enableScripts = priv->pageSettings->isScriptEnabled();
priv->settings.enablePlugins = priv->pageSettings->arePluginsEnabled();
priv->settings.enableFrameFlattening = priv->pageSettings->frameFlatteningEnabled();
#if ENABLE(FULLSCREEN_API)
priv->settings.enableFullscreen = priv->pageSettings->fullScreenEnabled();
#endif
priv->settings.enableXSSAuditor = priv->pageSettings->xssAuditorEnabled();
priv->settings.hyperlinkAuditingEnabled = priv->pageSettings->hyperlinkAuditingEnabled();
priv->settings.scriptsCanOpenWindows = priv->pageSettings->javaScriptCanOpenWindowsAutomatically();
priv->settings.scriptsCanCloseWindows = priv->pageSettings->allowScriptsToCloseWindows();
#if ENABLE(VIDEO_TRACK)
priv->settings.shouldDisplayCaptions = priv->pageSettings->shouldDisplayCaptions();
priv->settings.shouldDisplaySubtitles = priv->pageSettings->shouldDisplaySubtitles();
priv->settings.shouldDisplayTextDescriptions = priv->pageSettings->shouldDisplayTextDescriptions();
#endif
priv->settings.scriptsCanAccessClipboard = priv->pageSettings->javaScriptCanAccessClipboard() && priv->pageSettings->DOMPasteAllowed();
priv->settings.resizableTextareas = priv->pageSettings->textAreasAreResizable();
priv->settings.privateBrowsing = priv->pageSettings->privateBrowsingEnabled();
priv->settings.caretBrowsing = priv->pageSettings->caretBrowsingEnabled();
priv->settings.spatialNavigation = priv->pageSettings->spatialNavigationEnabled();
priv->settings.localStorage = priv->pageSettings->localStorageEnabled();
priv->settings.offlineAppCache = true; // XXX no function to read setting; this keeps the original setting
priv->settings.pageCache = priv->pageSettings->usesPageCache();
priv->settings.encodingDetector = priv->pageSettings->usesEncodingDetector();
priv->settings.webGLEnabled = priv->pageSettings->webGLEnabled();
priv->settings.tabsToLinks = true;
priv->settings.userAgent = ewk_settings_default_user_agent_get();
#if ENABLE(WEB_AUDIO)
priv->settings.webAudio = priv->pageSettings->webAudioEnabled();
#endif
// Since there's no scale separated from zooming in webkit-efl, this functionality of
// viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl,
// this functionality will be modified by the scale zoom patch.
priv->settings.zoomRange.minScale = zoomMinimum;
priv->settings.zoomRange.maxScale = zoomMaximum;
priv->settings.zoomRange.userScalable = true;
priv->settings.devicePixelRatio = devicePixelRatio;
priv->settings.domTimerInterval = priv->pageSettings->defaultMinDOMTimerInterval();
priv->settings.allowUniversalAccessFromFileURLs = priv->pageSettings->allowUniversalAccessFromFileURLs();
priv->settings.allowFileAccessFromFileURLs = priv->pageSettings->allowFileAccessFromFileURLs();
priv->mainFrame = _ewk_view_core_frame_new(smartData, priv, 0).get();
priv->history = ewk_history_new(static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList()));
priv->storageSession = WebCore::NetworkStorageSession::createDefaultSession();
priv->pageClient = adoptPtr(new PageClientEfl(smartData->self));
#ifdef HAVE_ECORE_X
priv->isUsingEcoreX = WebCore::isUsingEcoreX(smartData->base.evas);
#endif
#if ENABLE(CONTEXT_MENUS)
priv->contextMenu = 0;
#endif
#if USE(ACCELERATED_COMPOSITING)
priv->isCompositingActive = false;
#endif
return priv;
}
static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
{
if (!priv)
return;
/* do not delete priv->main_frame */
free(priv->repaints.array);
free(priv->scrolls.array);
eina_stringshare_del(priv->settings.userAgent);
eina_stringshare_del(priv->settings.userStylesheet);
eina_stringshare_del(priv->settings.encodingDefault);
eina_stringshare_del(priv->settings.encodingCustom);
eina_stringshare_del(priv->settings.fontStandard);
eina_stringshare_del(priv->settings.fontCursive);
eina_stringshare_del(priv->settings.fontMonospace);
eina_stringshare_del(priv->settings.fontFantasy);
eina_stringshare_del(priv->settings.fontSerif);
eina_stringshare_del(priv->settings.fontSansSerif);
eina_stringshare_del(priv->settings.localStorageDatabasePath);
if (priv->animatedZoom.animator)
ecore_animator_del(priv->animatedZoom.animator);
ewk_history_free(priv->history);
if (priv->cursorObject)
evas_object_del(priv->cursorObject);
#if ENABLE(CONTEXT_MENUS)
if (priv->contextMenu)
ewk_context_menu_free(priv->contextMenu);
#endif
#if USE(ACCELERATED_COMPOSITING)
priv->acceleratedCompositingContext = nullptr;
#endif
delete priv;
}
static void _ewk_view_smart_add(Evas_Object* ewkView)
{
const Evas_Smart* smart = evas_object_smart_smart_get(ewkView);
const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
EINA_SAFETY_ON_NULL_RETURN(api->backing_store_add);
EWK_VIEW_SD_GET(ewkView, smartData);
if (!smartData) {
smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
if (!smartData) {
CRITICAL("could not allocate Ewk_View_Smart_Data");
return;
}
evas_object_smart_data_set(ewkView, smartData);
}
smartData->bg_color.r = 255;
smartData->bg_color.g = 255;
smartData->bg_color.b = 255;
smartData->bg_color.a = 255;
smartData->self = ewkView;
smartData->api = api;
_parent_sc.add(ewkView);
smartData->_priv = _ewk_view_priv_new(smartData);
if (!smartData->_priv)
return;
EWK_VIEW_PRIV_GET(smartData, priv);
smartData->backing_store = api->backing_store_add(smartData);
if (!smartData->backing_store) {
ERR("Could not create backing store object.");
return;
}
evas_object_smart_member_add(smartData->backing_store, ewkView);
evas_object_show(smartData->backing_store);
evas_object_pass_events_set(smartData->backing_store, true);
smartData->events_rect = evas_object_rectangle_add(smartData->base.evas);
evas_object_color_set(smartData->events_rect, 0, 0, 0, 0);
evas_object_smart_member_add(smartData->events_rect, ewkView);
evas_object_show(smartData->events_rect);
smartData->main_frame = ewk_frame_add(smartData->base.evas);
if (!smartData->main_frame) {
ERR("Could not create main frame object.");
return;
}
if (!ewk_frame_init(smartData->main_frame, ewkView, priv->mainFrame)) {
ERR("Could not initialize main frme object.");
evas_object_del(smartData->main_frame);
smartData->main_frame = 0;
delete priv->mainFrame;
priv->mainFrame = 0;
return;
}
evas_object_name_set(smartData->main_frame, "EWK_Frame:main");
evas_object_smart_member_add(smartData->main_frame, ewkView);
evas_object_show(smartData->main_frame);
#define CONNECT(s, c) evas_object_event_callback_add(ewkView, s, c, smartData)
CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down);
CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up);
CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move);
CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
#undef CONNECT
}
static void _ewk_view_smart_del(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET(ewkView, smartData);
Ewk_View_Private_Data* priv = smartData ? smartData->_priv : 0;
ewk_view_stop(ewkView);
_parent_sc.del(ewkView);
_ewk_view_priv_del(priv);
}
static void _ewk_view_smart_resize(Evas_Object* ewkView, Evas_Coord w, Evas_Coord h)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
// these should be queued and processed in calculate as well!
evas_object_resize(smartData->backing_store, w, h);
smartData->changed.size = true;
_ewk_view_smart_changed(smartData);
}
static void _ewk_view_smart_move(Evas_Object* ewkView, Evas_Coord /*x*/, Evas_Coord /*y*/)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
smartData->changed.position = true;
_ewk_view_smart_changed(smartData);
}
static void _ewk_view_smart_calculate(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET(ewkView, smartData);
EWK_VIEW_PRIV_GET(smartData, priv);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->contents_resize);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->scrolls_process);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->repaints_process);
Evas_Coord x, y, width, height;
smartData->changed.any = false;
if (!smartData->main_frame || !priv->mainFrame)
return;
evas_object_geometry_get(ewkView, &x, &y, &width, &height);
DBG("ewkView=%p geo=[%d, %d + %dx%d], changed: size=%hhu, "
"scrolls=%zu, repaints=%zu",
ewkView, x, y, width, height, smartData->changed.size,
priv->scrolls.count, priv->repaints.count);
if (smartData->changed.size && ((width != smartData->view.w) || (height != smartData->view.h))) {
WebCore::FrameView* view = priv->mainFrame->view();
if (view) {
view->resize(width, height);
view->forceLayout();
view->adjustViewSize();
}
evas_object_resize(smartData->main_frame, width, height);
evas_object_resize(smartData->events_rect, width, height);
smartData->changed.frame_rect = true;
smartData->view.w = width;
smartData->view.h = height;
_ewk_view_repaint_add(priv, 0, 0, width, height);
// This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set).
evas_object_smart_callback_call(ewkView, "view,resized", 0);
}
smartData->changed.size = false;
if (smartData->changed.position && ((x != smartData->view.x) || (y != smartData->view.y))) {
evas_object_move(smartData->main_frame, x, y);
evas_object_move(smartData->backing_store, x, y);
evas_object_move(smartData->events_rect, x, y);
smartData->changed.frame_rect = true;
smartData->view.x = x;
smartData->view.y = y;
}
smartData->changed.position = false;
if (!smartData->api->scrolls_process(smartData))
ERR("failed to process scrolls.");
_ewk_view_scrolls_flush(priv);
if (!smartData->api->repaints_process(smartData))
ERR("failed to process repaints.");
if (smartData->changed.frame_rect) {
WebCore::FrameView* view = priv->mainFrame->view();
view->frameRectsChanged(); /* force tree to get position from root */
smartData->changed.frame_rect = false;
}
}
static void _ewk_view_smart_show(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
if (evas_object_clipees_get(smartData->base.clipper))
evas_object_show(smartData->base.clipper);
evas_object_show(smartData->backing_store);
}
static void _ewk_view_smart_hide(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
evas_object_hide(smartData->base.clipper);
evas_object_hide(smartData->backing_store);
}
static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data*, int /*width*/, int /*height*/)
{
return true;
}
static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
{
double px, py;
Evas_Coord x, y, width, height;
Eina_Bool result;
ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
ewk_frame_scroll_pos_get(smartData->main_frame, &x, &y);
if (width + smartData->view.w > 0)
px = static_cast<double>(x + centerX) / (width + smartData->view.w);
else
px = 0.0;
if (height + smartData->view.h > 0)
py = static_cast<double>(y + centerY) / (height + smartData->view.h);
else
py = 0.0;
result = ewk_frame_page_zoom_set(smartData->main_frame, zoom);
ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
x = (width + smartData->view.w) * px - centerX;
y = (height + smartData->view.h) * py - centerY;
ewk_frame_scroll_set(smartData->main_frame, x, y);
return result;
}
static void _ewk_view_smart_flush(Ewk_View_Smart_Data* smartData)
{
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
_ewk_view_repaints_flush(priv);
_ewk_view_scrolls_flush(priv);
}
static Eina_Bool _ewk_view_smart_pre_render_region(Ewk_View_Smart_Data* smartData, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
{
WARN("not supported by engine. smartData=%p area=%d,%d+%dx%d, zoom=%f",
smartData, x, y, width, height, zoom);
return false;
}
static Eina_Bool _ewk_view_smart_pre_render_relative_radius(Ewk_View_Smart_Data* smartData, unsigned int number, float zoom)
{
WARN("not supported by engine. smartData=%p, n=%u zoom=%f",
smartData, number, zoom);
return false;
}
static Eina_Bool _ewk_view_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
{
WARN("not supported by engine. smartData=%p", smartData);
return false;
}
static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
{
WARN("not supported by engine. smartData=%p", smartData);
}
static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* smartData)
{
smartData->animated_zoom.zoom.start = 0.0;
smartData->animated_zoom.zoom.end = 0.0;
smartData->animated_zoom.zoom.current = 0.0;
}
static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* smartData)
{
EWK_VIEW_PRIV_GET(smartData, priv);
ecore_animator_del(priv->animatedZoom.animator);
priv->animatedZoom.animator = 0;
_ewk_view_zoom_animated_mark_stop(smartData);
evas_object_smart_callback_call(smartData->self, "zoom,animated,end", 0);
}
static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv)
{
double now = ecore_loop_time_get();
double delta = now - priv->animatedZoom.time.start;
if (delta > priv->animatedZoom.time.duration)
delta = priv->animatedZoom.time.duration;
if (delta < 0.0) // time went back, clock adjusted?
delta = 0.0;
delta /= priv->animatedZoom.time.duration;
return ((priv->animatedZoom.zoom.range * delta)
+ priv->animatedZoom.zoom.start);
}
static Eina_Bool _ewk_view_zoom_animator_cb(void* data)
{
Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
Evas_Coord centerX, centerY;
EWK_VIEW_PRIV_GET(smartData, priv);
double now = ecore_loop_time_get();
centerX = priv->animatedZoom.center.x;
centerY = priv->animatedZoom.center.y;
// TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2)
if (centerX >= smartData->view.w)
centerX = smartData->view.w - 1;
if (centerY >= smartData->view.h)
centerY = smartData->view.h - 1;
if ((now >= priv->animatedZoom.time.end)
|| (now < priv->animatedZoom.time.start)) {
_ewk_view_zoom_animated_finish(smartData);
ewk_view_zoom_set(smartData->self, priv->animatedZoom.zoom.end, centerX, centerY);
smartData->api->sc.calculate(smartData->self);
return false;
}
smartData->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv);
smartData->api->zoom_weak_set(smartData, smartData->animated_zoom.zoom.current, centerX, centerY);
return true;
}
static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* smartData)
{
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
if (priv->animatedZoom.animator)
return;
priv->animatedZoom.animator = ecore_animator_add
(_ewk_view_zoom_animator_cb, smartData);
}
static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(Ewk_View_Private_Data* priv)
{
int desktopWidth = 980;
int deviceDPI = WebCore::getDPI();
priv->settings.devicePixelRatio = deviceDPI / WebCore::ViewportArguments::deprecatedTargetDPI;
WebCore::IntRect availableRect = enclosingIntRect(priv->page->chrome()->client()->pageRect());
WebCore::IntRect deviceRect = enclosingIntRect(priv->page->chrome()->client()->windowRect());
WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewportArguments, desktopWidth, deviceRect.width(), deviceRect.height(), priv->settings.devicePixelRatio, availableRect.size());
WebCore::restrictMinimumScaleFactorToViewportSize(attributes, availableRect.size(), priv->settings.devicePixelRatio);
WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
return attributes;
}
static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data* smartData)
{
WARN("not supported by engine. smartData=%p", smartData);
return false;
}
static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data* smartData)
{
WARN("not supported by engine. smartData=%p", smartData);
return false;
}
static const char* _ewk_view_editor_command_string_get(Ewk_View_Private_Data*, Ewk_Editor_Command ewkCommand)
{
static OwnPtr<Eina_Hash> editorCommandHash;
if (!editorCommandHash) {
editorCommandHash = adoptPtr(eina_hash_int32_new(0));
for (int i = 0; editorCommands[i].ewkEditorCommand != EWK_EDITOR_COMMAND_NONE; i++)
eina_hash_add(editorCommandHash.get(), &editorCommands[i].ewkEditorCommand, editorCommands[i].editorCommandString);
}
return reinterpret_cast<const char*>(eina_hash_find(editorCommandHash.get(), &ewkCommand));
}
Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class* api)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(api, false);
if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
EINA_LOG_CRIT
("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
return false;
}
if (EINA_UNLIKELY(!_parent_sc.add))
evas_object_smart_clipped_smart_set(&_parent_sc);
evas_object_smart_clipped_smart_set(&api->sc);
api->sc.add = _ewk_view_smart_add;
api->sc.del = _ewk_view_smart_del;
api->sc.resize = _ewk_view_smart_resize;
api->sc.move = _ewk_view_smart_move;
api->sc.calculate = _ewk_view_smart_calculate;
api->sc.show = _ewk_view_smart_show;
api->sc.hide = _ewk_view_smart_hide;
api->sc.data = ewkViewTypeString; /* used by type checking */
api->sc.callbacks = _ewk_view_callback_names;
api->contents_resize = _ewk_view_smart_contents_resize;
api->zoom_set = _ewk_view_smart_zoom_set;
api->flush = _ewk_view_smart_flush;
api->pre_render_region = _ewk_view_smart_pre_render_region;
api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
api->pre_render_start = _ewk_view_smart_pre_render_start;
api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
api->disable_render = _ewk_view_smart_disable_render;
api->enable_render = _ewk_view_smart_enable_render;
api->focus_in = _ewk_view_smart_focus_in;
api->focus_out = _ewk_view_smart_focus_out;
api->mouse_wheel = _ewk_view_smart_mouse_wheel;
api->mouse_down = _ewk_view_smart_mouse_down;
api->mouse_up = _ewk_view_smart_mouse_up;
api->mouse_move = _ewk_view_smart_mouse_move;
api->key_down = _ewk_view_smart_key_down;
api->key_up = _ewk_view_smart_key_up;
api->add_console_message = _ewk_view_smart_add_console_message;
api->run_javascript_alert = _ewk_view_smart_run_javascript_alert;
api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm;
api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt;
api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript;
return true;
}
void ewk_view_fixed_layout_size_set(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
WebCore::FrameView* view = priv->mainFrame->view();
if (!view)
return;
WebCore::IntSize layoutSize(width, height);
if (layoutSize.width() <= 0 && layoutSize.height() <= 0) {
if (!view->useFixedLayout())
return;
view->setUseFixedLayout(false);
} else {
WebCore::IntSize fixedLayoutSize = view->fixedLayoutSize();
if (fixedLayoutSize == layoutSize)
return;
view->setFixedLayoutSize(layoutSize);
view->setUseFixedLayout(true);
}
view->setNeedsLayout();
}
void ewk_view_fixed_layout_size_get(const Evas_Object* ewkView, Evas_Coord* width, Evas_Coord* height)
{
if (width)
*width = 0;
if (height)
*height = 0;
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
WebCore::FrameView* view = priv->mainFrame->view();
if (view->useFixedLayout()) {
WebCore::IntSize size = view->fixedLayoutSize();
if (width)
*width = size.width();
if (height)
*height = size.height();
}
}
void ewk_view_theme_set(Evas_Object* ewkView, const char* path)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
if (!eina_stringshare_replace(&priv->settings.theme, path))
return;
WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(priv->page->theme());
theme->setThemePath(path);
}
const char* ewk_view_theme_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.theme;
}
Evas_Object* ewk_view_frame_main_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
return smartData->main_frame;
}
Evas_Object* ewk_view_frame_focused_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
WebCore::Frame* core = priv->page->focusController()->focusedFrame();
if (!core)
return 0;
WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(core->loader()->client());
if (!client)
return 0;
return client->webFrame();
}
Eina_Bool ewk_view_uri_set(Evas_Object* ewkView, const char* uri)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_uri_set(smartData->main_frame, uri);
}
const char* ewk_view_uri_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
return ewk_frame_uri_get(smartData->main_frame);
}
const Ewk_Text_With_Direction* ewk_view_title_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
return ewk_frame_title_get(smartData->main_frame);
}
Eina_Bool ewk_view_editable_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_editable_get(smartData->main_frame);
}
void ewk_view_bg_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->bg_color_set);
if (alpha < 0) {
WARN("Alpha less than zero (%d).", alpha);
alpha = 0;
} else if (alpha > 255) {
WARN("Alpha is larger than 255 (%d).", alpha);
alpha = 255;
}
#define CHECK_PREMUL_COLOR(color, alpha) \
if (color < 0) { \
WARN("Color component " #color " is less than zero (%d).", color); \
color = 0; \
} else if (color > alpha) { \
WARN("Color component " #color " is greater than alpha (%d, alpha=%d).", \
color, alpha); \
color = alpha; \
}
CHECK_PREMUL_COLOR(red, alpha);
CHECK_PREMUL_COLOR(green, alpha);
CHECK_PREMUL_COLOR(blue, alpha);
#undef CHECK_PREMUL_COLOR
smartData->bg_color.r = red;
smartData->bg_color.g = green;
smartData->bg_color.b = blue;
smartData->bg_color.a = alpha;
smartData->api->bg_color_set(smartData, red, green, blue, alpha);
WebCore::FrameView* view = smartData->_priv->mainFrame->view();
if (view) {
WebCore::Color color;
if (!alpha)
color = WebCore::Color(0, 0, 0, 0);
else if (alpha == 255)
color = WebCore::Color(red, green, blue, alpha);
else
color = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
view->updateBackgroundRecursively(color, !alpha);
}
}
void ewk_view_bg_color_get(const Evas_Object* ewkView, int* red, int* green, int* blue, int* alpha)
{
if (red)
*red = 0;
if (green)
*green = 0;
if (blue)
*blue = 0;
if (alpha)
*alpha = 0;
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
if (red)
*red = smartData->bg_color.r;
if (green)
*green = smartData->bg_color.g;
if (blue)
*blue = smartData->bg_color.b;
if (alpha)
*alpha = smartData->bg_color.a;
}
Eina_Bool ewk_view_text_search(const Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(string, false);
WTF::TextCaseSensitivity sensitive;
WebCore::FindDirection direction;
if (caseSensitive)
sensitive = WTF::TextCaseSensitive;
else
sensitive = WTF::TextCaseInsensitive;
if (forward)
direction = WebCore::FindDirectionForward;
else
direction = WebCore::FindDirectionBackward;
return priv->page->findString(String::fromUTF8(string), sensitive, direction, wrap);
}
/**
* Mark matches the given text string in document.
*
* @param ewkView view object where to search text.
* @param string reference string to match.
* @param caseSensitive if match should be case sensitive or not.
* @param heightighlight if matches should be highlighted.
* @param limit maximum amount of matches, or zero to unlimited.
*
* @return number of matches.
*/
unsigned int ewk_view_text_matches_mark(Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
WTF::TextCaseSensitivity sensitive;
if (caseSensitive)
sensitive = WTF::TextCaseSensitive;
else
sensitive = WTF::TextCaseInsensitive;
return priv->page->markAllMatchesForText(String::fromUTF8(string), sensitive, highlight, limit);
}
Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
priv->page->unmarkAllTextMatches();
return true;
}
Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* ewkView, Eina_Bool highlight)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_text_matches_highlight_set(smartData->main_frame, highlight);
}
Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_text_matches_highlight_get(smartData->main_frame);
}
Eina_Bool ewk_view_editable_set(Evas_Object* ewkView, Eina_Bool editable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_editable_set(smartData->main_frame, editable);
}
const char* ewk_view_selection_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
CString selectedString = priv->page->focusController()->focusedOrMainFrame()->editor().selectedText().utf8();
if (selectedString.isNull())
return 0;
return eina_stringshare_add(selectedString.data());
}
Eina_Bool ewk_view_editor_command_execute(const Evas_Object* ewkView, const Ewk_Editor_Command command, const char* value)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
const char* commandString = _ewk_view_editor_command_string_get(priv, command);
if (!commandString)
return false;
return priv->page->focusController()->focusedOrMainFrame()->editor().command(commandString).execute(WTF::String::fromUTF8(value));
}
Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* ewkView, const Evas_Event_Mouse_Down* downEvent)
{
#if ENABLE(CONTEXT_MENUS)
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
Eina_Bool mouse_press_handled = false;
priv->page->contextMenuController()->clearContextMenu();
if (priv->contextMenu)
ewk_context_menu_free(priv->contextMenu);
WebCore::Frame* mainFrame = priv->page->mainFrame();
Evas_Coord x, y;
evas_object_geometry_get(smartData->self, &x, &y, 0, 0);
WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
if (mainFrame->view()) {
mouse_press_handled =
mainFrame->eventHandler()->handleMousePressEvent(event);
}
if (!mainFrame->eventHandler()->sendContextMenuEvent(event))
return false;
WebCore::ContextMenu* coreMenu =
priv->page->contextMenuController()->contextMenu();
if (!coreMenu) {
// WebCore decided not to create a context menu, return true if event
// was handled by handleMouseReleaseEvent
return mouse_press_handled;
}
priv->contextMenu = ewk_context_menu_new(ewkView, priv->page->contextMenuController(), coreMenu);
if (!priv->contextMenu)
return false;
ewk_context_menu_show(priv->contextMenu);
return true;
#else
UNUSED_PARAM(ewkView);
UNUSED_PARAM(downEvent);
return false;
#endif
}
double ewk_view_load_progress_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
return priv->page->progress()->estimatedProgress();
}
Eina_Bool ewk_view_stop(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_stop(smartData->main_frame);
}
Eina_Bool ewk_view_reload(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_reload(smartData->main_frame);
}
Eina_Bool ewk_view_reload_full(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_reload_full(smartData->main_frame);
}
Eina_Bool ewk_view_back(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_back(smartData->main_frame);
}
Eina_Bool ewk_view_forward(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_forward(smartData->main_frame);
}
Eina_Bool ewk_view_navigate(Evas_Object* ewkView, int steps)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_navigate(smartData->main_frame, steps);
}
Eina_Bool ewk_view_back_possible(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_back_possible(smartData->main_frame);
}
Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_forward_possible(smartData->main_frame);
}
Eina_Bool ewk_view_navigate_possible(Evas_Object* ewkView, int steps)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_navigate_possible(smartData->main_frame, steps);
}
Eina_Bool ewk_view_history_enable_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled();
}
Eina_Bool ewk_view_history_enable_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->setEnabled(enable);
return true;
}
Ewk_History* ewk_view_history_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
if (!static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled()) {
ERR("asked history, but it's disabled! Returning 0!");
return 0;
}
return priv->history;
}
Eina_Bool ewk_view_visited_link_add(Evas_Object* ewkView, const char* visitedUrl)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv->page, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(priv->page->groupPtr(), false);
WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(visitedUrl));
priv->page->groupPtr()->addVisitedLink(kurl);
return true;
}
float ewk_view_zoom_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
return ewk_frame_page_zoom_get(smartData->main_frame);
}
Eina_Bool ewk_view_zoom_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET(smartData, priv);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_set, false);
if (!priv->settings.zoomRange.userScalable) {
WARN("userScalable is false");
return false;
}
if (zoom < priv->settings.zoomRange.minScale) {
WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
return false;
}
if (zoom > priv->settings.zoomRange.maxScale) {
WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
return false;
}
_ewk_view_zoom_animated_mark_stop(smartData);
return smartData->api->zoom_set(smartData, zoom, centerX, centerY);
}
float ewk_view_page_zoom_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
return ewk_frame_page_zoom_get(smartData->main_frame);
}
Eina_Bool ewk_view_page_zoom_set(Evas_Object* ewkView, float pageZoomFactor)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_page_zoom_set(smartData->main_frame, pageZoomFactor);
}
float ewk_view_scale_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
return priv->page->pageScaleFactor();
}
Eina_Bool ewk_view_scale_set(Evas_Object* ewkView, float scaleFactor, Evas_Coord scrollX, Evas_Coord scrollY)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
float currentScaleFactor = ewk_view_scale_get(ewkView);
if (currentScaleFactor == -1)
return false;
priv->page->setPageScaleFactor(scaleFactor, WebCore::IntPoint(scrollX, scrollY));
return true;
}
float ewk_view_text_zoom_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
return ewk_frame_text_zoom_get(smartData->main_frame);
}
Eina_Bool ewk_view_text_zoom_set(Evas_Object* ewkView, float textZoomFactor)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return ewk_frame_text_zoom_set(smartData->main_frame, textZoomFactor);
}
Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
return smartData->zoom_weak_smooth_scale;
}
void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* ewkView, Eina_Bool smoothScale)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
smoothScale = !!smoothScale;
if (smartData->zoom_weak_smooth_scale == smoothScale)
return;
smartData->zoom_weak_smooth_scale = smoothScale;
EINA_SAFETY_ON_NULL_RETURN(smartData->api);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->zoom_weak_smooth_scale_set);
smartData->api->zoom_weak_smooth_scale_set(smartData, smoothScale);
}
Eina_Bool ewk_view_zoom_weak_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET(smartData, priv);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, false);
if (!priv->settings.zoomRange.userScalable) {
WARN("userScalable is false");
return false;
}
if (zoom < priv->settings.zoomRange.minScale) {
WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
return false;
}
if (zoom > priv->settings.zoomRange.maxScale) {
WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
return false;
}
smartData->animated_zoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
smartData->animated_zoom.zoom.end = zoom;
smartData->animated_zoom.zoom.current = zoom;
return smartData->api->zoom_weak_set(smartData, zoom, centerX, centerY);
}
Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* ewkView, float zoom)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
smartData->animated_zoom.zoom.start = zoom;
return true;
}
Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* ewkView, float zoom)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
smartData->animated_zoom.zoom.end = zoom;
return true;
}
Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* ewkView, float zoom)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
smartData->animated_zoom.zoom.current = zoom;
return true;
}
Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
_ewk_view_zoom_animated_mark_stop(smartData);
return true;
}
Eina_Bool ewk_view_zoom_animated_set(Evas_Object* ewkView, float zoom, float duration, Evas_Coord centerX, Evas_Coord centerY)
{
double now;
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, false);
if (!priv->settings.zoomRange.userScalable) {
WARN("userScalable is false");
return false;
}
if (zoom < priv->settings.zoomRange.minScale) {
WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
return false;
}
if (zoom > priv->settings.zoomRange.maxScale) {
WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
return false;
}
if (priv->animatedZoom.animator)
priv->animatedZoom.zoom.start = _ewk_view_zoom_animated_current(priv);
else {
priv->animatedZoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
_ewk_view_zoom_animation_start(smartData);
}
if (centerX < 0)
centerX = 0;
if (centerY < 0)
centerY = 0;
now = ecore_loop_time_get();
priv->animatedZoom.time.start = now;
priv->animatedZoom.time.end = now + duration;
priv->animatedZoom.time.duration = duration;
priv->animatedZoom.zoom.end = zoom;
priv->animatedZoom.zoom.range = (priv->animatedZoom.zoom.end - priv->animatedZoom.zoom.start);
priv->animatedZoom.center.x = centerX;
priv->animatedZoom.center.y = centerY;
smartData->animated_zoom.zoom.current = priv->animatedZoom.zoom.start;
smartData->animated_zoom.zoom.start = priv->animatedZoom.zoom.start;
smartData->animated_zoom.zoom.end = priv->animatedZoom.zoom.end;
return true;
}
Eina_Bool ewk_view_pre_render_region(Evas_Object* ewkView, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_region, false);
float currentZoom;
Evas_Coord contentsWidth, contentsHeight;
/* When doing animated zoom it's not possible to call pre-render since it
* would screw up parameters that animation is currently using
*/
if (priv->animatedZoom.animator)
return false;
currentZoom = ewk_frame_page_zoom_get(smartData->main_frame);
if (currentZoom < 0.00001)
return false;
if (!ewk_frame_contents_size_get(smartData->main_frame, &contentsWidth, &contentsHeight))
return false;
contentsWidth *= zoom / currentZoom;
contentsHeight *= zoom / currentZoom;
DBG("region %d,%d+%dx%d @ %f contents=%dx%d", x, y, width, height, zoom, contentsWidth, contentsHeight);
if (x + width > contentsWidth)
width = contentsWidth - x;
if (y + height > contentsHeight)
height = contentsHeight - y;
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
return smartData->api->pre_render_region(smartData, x, y, width, height, zoom);
}
Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object* ewkView, unsigned int number)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_relative_radius, false);
float currentZoom;
if (priv->animatedZoom.animator)
return false;
currentZoom = ewk_frame_page_zoom_get(smartData->main_frame);
return smartData->api->pre_render_relative_radius(smartData, number, currentZoom);
}
Eina_Bool ewk_view_pre_render_start(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->pre_render_start, false);
return smartData->api->pre_render_start(smartData);
}
unsigned int ewk_view_imh_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->imh;
}
void ewk_view_pre_render_cancel(Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
EINA_SAFETY_ON_NULL_RETURN(smartData->api->pre_render_cancel);
smartData->api->pre_render_cancel(smartData);
}
Eina_Bool ewk_view_enable_render(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->enable_render, false);
return smartData->api->enable_render(smartData);
}
Eina_Bool ewk_view_disable_render(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->disable_render, false);
return smartData->api->disable_render(smartData);
}
const char* ewk_view_setting_user_agent_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.userAgent;
}
Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* ewkView, const char* userAgent)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
if (eina_stringshare_replace(&priv->settings.userAgent, userAgent)) {
WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(priv->mainFrame->loader()->client());
client->setCustomUserAgent(String::fromUTF8(userAgent));
}
return true;
}
const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.userStylesheet;
}
Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* ewkView, const char* uri)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
if (eina_stringshare_replace(&priv->settings.userStylesheet, uri)) {
WebCore::KURL kurl(WebCore::KURL(), String::fromUTF8(uri));
priv->pageSettings->setUserStyleSheetLocation(kurl);
}
return true;
}
Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.autoLoadImages;
}
Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* ewkView, Eina_Bool automatic)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
automatic = !!automatic;
if (priv->settings.autoLoadImages != automatic) {
priv->pageSettings->setLoadsImagesAutomatically(automatic);
priv->settings.autoLoadImages = automatic;
}
return true;
}
Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.autoShrinkImages;
}
Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* ewkView, Eina_Bool automatic)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
automatic = !!automatic;
if (priv->settings.autoShrinkImages != automatic) {
priv->pageSettings->setShrinksStandaloneImagesToFit(automatic);
priv->settings.autoShrinkImages = automatic;
}
return true;
}
Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.enableAutoResizeWindow;
}
Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* ewkView, Eina_Bool resizable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
priv->settings.enableAutoResizeWindow = resizable;
return true;
}
Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.enableScripts;
}
Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.enableScripts != enable) {
priv->pageSettings->setScriptEnabled(enable);
priv->settings.enableScripts = enable;
}
return true;
}
Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.enablePlugins;
}
Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.enablePlugins != enable) {
priv->pageSettings->setPluginsEnabled(enable);
priv->settings.enablePlugins = enable;
}
return true;
}
Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.enableFrameFlattening;
}
Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.enableFrameFlattening != enable) {
priv->pageSettings->setFrameFlatteningEnabled(enable);
priv->settings.enableFrameFlattening = enable;
}
return true;
}
Eina_Bool ewk_view_setting_scripts_can_open_windows_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.scriptsCanOpenWindows;
}
Eina_Bool ewk_view_setting_scripts_can_open_windows_set(Evas_Object* ewkView, Eina_Bool allow)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
allow = !!allow;
if (priv->settings.scriptsCanOpenWindows != allow) {
priv->pageSettings->setJavaScriptCanOpenWindowsAutomatically(allow);
priv->settings.scriptsCanOpenWindows = allow;
}
return true;
}
Eina_Bool ewk_view_setting_scripts_can_close_windows_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.scriptsCanCloseWindows;
}
Eina_Bool ewk_view_setting_scripts_can_close_windows_set(Evas_Object* ewkView, Eina_Bool allow)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
allow = !!allow;
if (priv->settings.scriptsCanCloseWindows != allow) {
priv->pageSettings->setAllowScriptsToCloseWindows(allow);
priv->settings.scriptsCanCloseWindows = allow;
}
return true;
}
Eina_Bool ewk_view_setting_scripts_can_access_clipboard_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.scriptsCanAccessClipboard;
}
Eina_Bool ewk_view_setting_scripts_can_access_clipboard_set(Evas_Object* ewkView, Eina_Bool allow)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
allow = !!allow;
if (priv->settings.scriptsCanAccessClipboard != allow) {
priv->pageSettings->setJavaScriptCanAccessClipboard(allow);
priv->pageSettings->setDOMPasteAllowed(allow);
priv->settings.scriptsCanAccessClipboard = allow;
}
return true;
}
Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.resizableTextareas;
}
Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.resizableTextareas != enable) {
priv->pageSettings->setTextAreasAreResizable(enable);
priv->settings.resizableTextareas = enable;
}
return true;
}
Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.privateBrowsing;
}
Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.privateBrowsing != enable) {
priv->pageSettings->setPrivateBrowsingEnabled(enable);
priv->settings.privateBrowsing = enable;
}
return true;
}
Eina_Bool ewk_view_setting_application_cache_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.offlineAppCache;
}
Eina_Bool ewk_view_setting_application_cache_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.offlineAppCache != enable) {
priv->pageSettings->setOfflineWebApplicationCacheEnabled(enable);
priv->settings.offlineAppCache = enable;
}
return true;
}
Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.caretBrowsing;
}
Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.caretBrowsing != enable) {
priv->pageSettings->setCaretBrowsingEnabled(enable);
priv->settings.caretBrowsing = enable;
}
return true;
}
const char* ewk_view_setting_encoding_custom_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
WebCore::Frame* core_frame = EWKPrivate::coreFrame(main_frame);
String overrideEncoding = core_frame->loader()->documentLoader()->overrideEncoding();
if (overrideEncoding.isEmpty())
return 0;
eina_stringshare_replace(&priv->settings.encodingCustom, overrideEncoding.utf8().data());
return priv->settings.encodingCustom;
}
Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* ewkView, const char* encoding)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
WebCore::Frame* coreFrame = EWKPrivate::coreFrame(main_frame);
DBG("%s", encoding);
if (eina_stringshare_replace(&priv->settings.encodingCustom, encoding))
coreFrame->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding));
return true;
}
const char* ewk_view_setting_encoding_default_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.encodingDefault;
}
Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* ewkView, const char* encoding)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
if (eina_stringshare_replace(&priv->settings.encodingDefault, encoding))
priv->pageSettings->setDefaultTextEncodingName(String::fromUTF8(encoding));
return true;
}
Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.encodingDetector != enable) {
priv->pageSettings->setUsesEncodingDetector(enable);
priv->settings.encodingDetector = enable;
}
return true;
}
Eina_Bool ewk_view_setting_encoding_detector_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.encodingDetector;
}
Eina_Bool ewk_view_setting_enable_developer_extras_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
return priv->settings.enableDeveloperExtras;
}
Eina_Bool ewk_view_setting_enable_developer_extras_set(Evas_Object* ewkView, Eina_Bool enable)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
enable = !!enable;
if (priv->settings.enableDeveloperExtras != enable) {
priv->pageSettings->setDeveloperExtrasEnabled(enable);
priv->settings.enableDeveloperExtras = enable;
}
return true;
}
int ewk_view_setting_font_minimum_size_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.fontMinimumSize;
}
Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* ewkView, int size)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
if (priv->settings.fontMinimumSize != size) {
priv->pageSettings->setMinimumFontSize(size);
priv->settings.fontMinimumSize = size;
}
return true;
}
int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* ewkView)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
return priv->settings.fontMinimumLogicalSize;
}
Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* ewkView, int size)
{
EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
if (priv->settings.fontMinimumLogicalSize != size) {
priv->pageSettings->setMinimumLogicalFontSize(size);
priv->settings.fontMinimumLogicalSize =