Removing PAGE_VISIBILITY_API compile guard.
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_view.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2012 Samsung Electronics
4     Copyright (C) 2012 Intel Corporation
5     Copyright (C) 2013 Apple Inc. All rights reserved.
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22
23 #define __STDC_FORMAT_MACROS
24 #include "config.h"
25 #include "ewk_view.h"
26
27 #include "AcceleratedCompositingContextEfl.h"
28 #include "BackForwardController.h"
29 #include "BackForwardList.h"
30 #include "Bridge.h"
31 #include "Chrome.h"
32 #include "ChromeClientEfl.h"
33 #include "ContextMenuClientEfl.h"
34 #include "ContextMenuController.h"
35 #include "DocumentLoader.h"
36 #include "DragClientEfl.h"
37 #include "DumpRenderTreeSupportEfl.h"
38 #include "Editor.h"
39 #include "EditorClientEfl.h"
40 #include "EflScreenUtilities.h"
41 #include "EventHandler.h"
42 #include "FocusController.h"
43 #include "FrameLoaderClientEfl.h"
44 #include "FrameSelection.h"
45 #include "FrameView.h"
46 #include "GraphicsContext.h"
47 #include "HTMLElement.h"
48 #include "HTMLInputElement.h"
49 #include "HTMLNames.h"
50 #include "InspectorClientEfl.h"
51 #include "InspectorController.h"
52 #include "IntSize.h"
53 #include "JSDOMBinding.h"
54 #include "JSDOMWindow.h"
55 #include "JSLock.h"
56 #include "MainFrame.h"
57 #include "NetworkStorageSession.h"
58 #include "Operations.h"
59 #include "PageGroup.h"
60 #include "PlatformMouseEvent.h"
61 #include "PopupMenuClient.h"
62 #include "ProgressTracker.h"
63 #include "ProgressTrackerClientEfl.h"
64 #include "RefPtrCairo.h"
65 #include "RenderThemeEfl.h"
66 #include "ResourceHandle.h"
67 #include "RuntimeEnabledFeatures.h"
68 #include "ScriptController.h"
69 #include "SessionID.h"
70 #include "Settings.h"
71 #include "SoupNetworkSession.h"
72 #include "c_instance.h"
73 #include "ewk_contextmenu_private.h"
74 #include "ewk_frame.h"
75 #include "ewk_frame_private.h"
76 #include "ewk_history_private.h"
77 #include "ewk_js_private.h"
78 #include "ewk_private.h"
79 #include "ewk_settings_private.h"
80 #include "ewk_view_private.h"
81 #include "ewk_window_features_private.h"
82 #include <Ecore.h>
83 #include <Ecore_Evas.h>
84 #include <Edje.h>
85 #include <Eina.h>
86 #include <Evas.h>
87 #include <eina_safety_checks.h>
88 #include <inttypes.h>
89 #include <limits>
90 #include <math.h>
91 #include <sys/time.h>
92
93 #if ENABLE(DEVICE_ORIENTATION)
94 #include "DeviceMotionClientEfl.h"
95 #include "DeviceOrientationClientEfl.h"
96 #endif
97
98 #if ENABLE(GEOLOCATION)
99 #include "GeolocationClientMock.h"
100 #include "GeolocationController.h"
101 #endif
102
103 #if ENABLE(VIBRATION)
104 #include "VibrationClientEfl.h"
105 #endif
106
107 #if ENABLE(BATTERY_STATUS)
108 #include "BatteryClientEfl.h"
109 #endif
110
111 #if ENABLE(INPUT_TYPE_COLOR)
112 #include "ColorChooserClient.h"
113 #endif
114
115 #if ENABLE(NAVIGATOR_CONTENT_UTILS)
116 #include "NavigatorContentUtilsClientEfl.h"
117 #endif
118
119 static const float zoomMinimum = 0.05;
120 static const float zoomMaximum = 4.0;
121
122 static const char ewkViewTypeString[] = "EWK_View";
123
124 static const size_t ewkViewRepaintsSizeInitial = 32;
125 static const size_t ewkViewRepaintsSizeStep = 8;
126 static const size_t ewkViewRepaintsSizeMaximumFree = 64;
127
128 static const Evas_Smart_Cb_Description _ewk_view_callback_names[] = {
129     { "colorchooser,create", "(yyyy)" },
130     { "colorchooser,willdelete", "" },
131     { "colorchooser,color,changed", "(yyyy)" },
132     { "download,request", "p" },
133     { "editorclient,contents,changed", "" },
134     { "editorclient,selection,changed", "" },
135     { "frame,created", "p" },
136     { "icon,received", "" },
137     { "inputmethod,changed", "b" },
138     { "js,windowobject,clear", "" },
139     { "link,hover,in", "p" },
140     { "link,hover,out", "" },
141     { "load,document,finished", "p" },
142     { "load,error", "p" },
143     { "load,finished", "p" },
144     { "load,newwindow,show", "" },
145     { "load,progress", "d" },
146     { "load,provisional", "" },
147     { "load,started", "" },
148     { "menubar,visible,get", "b" },
149     { "menubar,visible,set", "b" },
150     { "popup,created", "p" },
151     { "popup,willdelete", "p" },
152     { "ready", "" },
153     { "scrollbars,visible,get", "b" },
154     { "scrollbars,visible,set", "b" },
155     { "statusbar,text,set", "s" },
156     { "statusbar,visible,get", "b" },
157     { "statusbar,visible,set", "b" },
158     { "title,changed", "s" },
159     { "toolbars,visible,get", "b" },
160     { "toolbars,visible,set", "b" },
161     { "tooltip,text,set", "s" },
162     { "tooltip,text,unset", "s" },
163     { "uri,changed", "s" },
164     { "view,resized", "" },
165     { "zoom,animated,end", "" },
166     { 0, 0 }
167 };
168
169 struct EditorCommand {
170     Ewk_Editor_Command ewkEditorCommand;
171     const char* editorCommandString;
172 };
173
174 /**
175  * @brief A table grouping Ewk_Editor_Command enums with corresponding command
176  * strings used by WebCore::EditorCommand, keeping both in sync.
177  *
178  * @internal
179  */
180 static const EditorCommand editorCommands[] = {
181     { EWK_EDITOR_COMMAND_UNDO, "Undo" },
182     { EWK_EDITOR_COMMAND_REDO, "Redo" },
183     { EWK_EDITOR_COMMAND_TOGGLE_BOLD, "ToggleBold" },
184     { EWK_EDITOR_COMMAND_TOGGLE_ITALIC, "ToggleItalic" },
185     { EWK_EDITOR_COMMAND_TOGGLE_UNDERLINE, "ToggleUnderline" },
186     { EWK_EDITOR_COMMAND_TOGGLE_STRIKETHROUGH, "Strikethrough" },
187     { EWK_EDITOR_COMMAND_TOGGLE_SUBSCRIPT, "SubScript" },
188     { EWK_EDITOR_COMMAND_TOGGLE_SUPERSCRIPT, "SuperScript" },
189     { EWK_EDITOR_COMMAND_INDENT, "Indent" },
190     { EWK_EDITOR_COMMAND_OUTDENT, "Outdent" },
191     { EWK_EDITOR_COMMAND_INSERT_ORDEREDLIST, "InsertOrderedList" },
192     { EWK_EDITOR_COMMAND_INSERT_UNORDEREDLIST, "InsertUnorderedList" },
193     { EWK_EDITOR_COMMAND_INSERT_IMAGE, "InsertImage" },
194     { EWK_EDITOR_COMMAND_INSERT_TEXT, "InsertText" },
195     { EWK_EDITOR_COMMAND_INSERT_HTML, "InsertHTML" },
196     { EWK_EDITOR_COMMAND_INSERT_PARAGRAPH, "InsertParagraph" },
197     { EWK_EDITOR_COMMAND_INSERT_PARAGRAPH_SEPARATOR, "InsertNewLine" },
198     { EWK_EDITOR_COMMAND_INSERT_LINE_SEPARATOR, "InsertLineBreak" },
199     { EWK_EDITOR_COMMAND_BACK_COLOR, "BackColor" },
200     { EWK_EDITOR_COMMAND_FORE_COLOR, "ForeColor" },
201     { EWK_EDITOR_COMMAND_HILITE_COLOR, "HiliteColor" },
202     { EWK_EDITOR_COMMAND_FONT_SIZE, "FontSize" },
203     { EWK_EDITOR_COMMAND_ALIGN_CENTER, "AlignCenter" },
204     { EWK_EDITOR_COMMAND_ALIGN_JUSTIFIED, "AlignJustified" },
205     { EWK_EDITOR_COMMAND_ALIGN_LEFT, "AlignLeft" },
206     { EWK_EDITOR_COMMAND_ALIGN_RIGHT, "AlignRight" },
207     { EWK_EDITOR_COMMAND_MOVE_TO_NEXT_CHAR, "MoveForward" },
208     { EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_CHAR, "MoveBackward" },
209     { EWK_EDITOR_COMMAND_MOVE_TO_NEXT_WORD, "MoveWordForward" },
210     { EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_WORD, "MoveWordBackward" },
211     { EWK_EDITOR_COMMAND_MOVE_TO_NEXT_LINE, "MoveDown" },
212     { EWK_EDITOR_COMMAND_MOVE_TO_PREVIOUS_LINE, "MoveUp" },
213     { EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_LINE, "MoveToBeginningOfLine" },
214     { EWK_EDITOR_COMMAND_MOVE_TO_END_OF_LINE, "MoveToEndOfLine" },
215     { EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_PARAGRAPH, "MoveToBeginningOfParagraph" },
216     { EWK_EDITOR_COMMAND_MOVE_TO_END_OF_PARAGRAPH, "MoveToEndOfParagraph" },
217     { EWK_EDITOR_COMMAND_MOVE_TO_BEGINNING_OF_DOCUMENT, "MoveToBeginningOfDocument" },
218     { EWK_EDITOR_COMMAND_MOVE_TO_END_OF_DOCUMENT, "MoveToEndOfDocument" },
219     { EWK_EDITOR_COMMAND_SELECT_NONE, "SelectNone" },
220     { EWK_EDITOR_COMMAND_SELECT_ALL, "SelectAll" },
221     { EWK_EDITOR_COMMAND_SELECT_PARAGRAPH, "SelectParagraph" },
222     { EWK_EDITOR_COMMAND_SELECT_SENTENCE, "SelectSentence" },
223     { EWK_EDITOR_COMMAND_SELECT_LINE, "SelectLine" },
224     { EWK_EDITOR_COMMAND_SELECT_WORD, "SelectWord" },
225     { EWK_EDITOR_COMMAND_SELECT_NEXT_CHAR, "MoveForwardAndModifySelection" },
226     { EWK_EDITOR_COMMAND_SELECT_PREVIOUS_CHAR, "MoveBackwardAndModifySelection" },
227     { EWK_EDITOR_COMMAND_SELECT_NEXT_WORD, "MoveWordForwardAndModifySelection" },
228     { EWK_EDITOR_COMMAND_SELECT_PREVIOUS_WORD, "MoveWordBackwardAndModifySelection" },
229     { EWK_EDITOR_COMMAND_SELECT_NEXT_LINE, "MoveDownAndModifySelection" },
230     { EWK_EDITOR_COMMAND_SELECT_PREVIOUS_LINE, "MoveUpAndModifySelection" },
231     { EWK_EDITOR_COMMAND_SELECT_START_OF_LINE, "MoveToBeginningOfLineAndModifySelection" },
232     { EWK_EDITOR_COMMAND_SELECT_END_OF_LINE, "MoveToEndOfLineAndModifySelection" },
233     { EWK_EDITOR_COMMAND_SELECT_START_OF_PARAGRAPH, "MoveToBeginningOfParagraphAndModifySelection" },
234     { EWK_EDITOR_COMMAND_SELECT_END_OF_PARAGRAPH, "MoveToEndOfParagraphAndModifySelection" },
235     { EWK_EDITOR_COMMAND_SELECT_START_OF_DOCUMENT, "MoveToBeginningOfDocumentAndModifySelection" },
236     { EWK_EDITOR_COMMAND_SELECT_END_OF_DOCUMENT, "MoveToEndOfDocumentAndModifySelection" },
237     { EWK_EDITOR_COMMAND_DELETE_WORD_BACKWARD, "DeleteWordBackward" },
238     { EWK_EDITOR_COMMAND_DELETE_WORD_FORWARD, "DeleteWordForward" },
239     { EWK_EDITOR_COMMAND_NONE, 0 } // EWK_EDITOR_COMMAND_NONE must be the last element.
240 };
241
242 /**
243  * @brief Private data that is used internally by EFL WebKit
244  * and should never be modified from outside.
245  *
246  * @internal
247  */
248 struct _Ewk_View_Private_Data {
249     OwnPtr<WebCore::Page> page;
250     WebCore::ViewportArguments viewportArguments;
251     Ewk_History* history;
252     std::unique_ptr<WebCore::AcceleratedCompositingContext> acceleratedCompositingContext;
253 #if ENABLE(INPUT_TYPE_COLOR)
254     WebCore::ColorChooserClient* colorChooserClient;
255 #endif
256     struct {
257         Ewk_Menu menu;
258         WebCore::PopupMenuClient* menuClient;
259     } popup;
260     unsigned int imh; /**< input method hints */
261     struct {
262         bool viewCleared : 1;
263         bool needTouchEvents : 1;
264         bool hasDisplayedMixedContent : 1;
265         bool hasRunMixedContent : 1;
266     } flags;
267     struct {
268         const char* userAgent;
269         const char* userStylesheet;
270         const char* encodingDefault;
271         const char* encodingCustom;
272         const char* theme;
273         const char* localStorageDatabasePath;
274         int fontMinimumSize;
275         int fontMinimumLogicalSize;
276         int fontDefaultSize;
277         int fontMonospaceSize;
278         const char* fontStandard;
279         const char* fontCursive;
280         const char* fontMonospace;
281         const char* fontFantasy;
282         const char* fontSerif;
283         const char* fontSansSerif;
284         bool autoLoadImages : 1;
285         bool autoShrinkImages : 1;
286         bool enableAutoResizeWindow : 1;
287         bool enableDeveloperExtras : 1;
288         bool enableScripts : 1;
289         bool enablePlugins : 1;
290         bool enableFrameFlattening : 1;
291 #if ENABLE(FULLSCREEN_API)
292         bool enableFullscreen : 1;
293 #endif
294         bool encodingDetector : 1;
295         bool hyperlinkAuditingEnabled : 1;
296         bool scriptsCanOpenWindows : 1;
297         bool scriptsCanCloseWindows : 1;
298 #if ENABLE(VIDEO_TRACK)
299         bool shouldDisplayCaptions : 1;
300         bool shouldDisplaySubtitles : 1;
301         bool shouldDisplayTextDescriptions: 1;
302 #endif
303         bool scriptsCanAccessClipboard : 1;
304         bool resizableTextareas : 1;
305         bool privateBrowsing : 1;
306         bool caretBrowsing : 1;
307         bool spatialNavigation : 1;
308         bool localStorage : 1;
309         bool offlineAppCache : 1;
310         bool pageCache : 1;
311         bool enableXSSAuditor : 1;
312         bool webGLEnabled : 1;
313         bool tabsToLinks : 1;
314         struct {
315             float minScale;
316             float maxScale;
317             Eina_Bool userScalable : 1;
318         } zoomRange;
319         double domTimerInterval;
320         bool allowUniversalAccessFromFileURLs : 1;
321         bool allowFileAccessFromFileURLs : 1;
322     } settings;
323     struct {
324         struct {
325             double start;
326             double end;
327             double duration;
328         } time;
329         struct {
330             float start;
331             float end;
332             float range;
333         } zoom;
334         struct {
335             Evas_Coord x, y;
336         } center;
337         Ecore_Animator* animator;
338     } animatedZoom;
339     const char* cursorGroup;
340     Evas_Object* cursorObject;
341 #if ENABLE(INSPECTOR)
342     Evas_Object* inspectorView;
343 #endif
344 #if ENABLE(CONTEXT_MENUS)
345     Ewk_Context_Menu* contextMenu;
346 #endif
347 };
348
349 #ifndef EWK_TYPE_CHECK
350 #define EWK_VIEW_TYPE_CHECK(ewkView, ...) do { } while (0)
351 #else
352 #define EWK_VIEW_TYPE_CHECK(ewkView, ...) \
353     do { \
354         const char* _tmp_otype = evas_object_type_get(ewkView); \
355         const Evas_Smart* _tmp_s = evas_object_smart_smart_get(ewkView); \
356         if (EINA_UNLIKELY(!_tmp_s)) { \
357             EINA_LOG_CRIT \
358                 ("%p (%s) is not a smart object!", ewkView, \
359                 _tmp_otype ? _tmp_otype : "(null)"); \
360             return __VA_ARGS__; \
361         } \
362         const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \
363         if (EINA_UNLIKELY(!_tmp_sc)) { \
364             EINA_LOG_CRIT \
365                 ("%p (%s) is not a smart object!", ewkView, \
366                 _tmp_otype ? _tmp_otype : "(null)"); \
367             return __VA_ARGS__; \
368         } \
369         if (EINA_UNLIKELY(_tmp_sc->data != ewkViewTypeString)) { \
370             EINA_LOG_CRIT \
371                 ("%p (%s) is not of an ewk_view (need %p, got %p)!", \
372                 ewkView, _tmp_otype ? _tmp_otype : "(null)", \
373                 ewkViewTypeString, _tmp_sc->data); \
374             return __VA_ARGS__; \
375         } \
376     } while (0)
377 #endif
378
379 #define EWK_VIEW_SD_GET(ewkView, pointer) \
380     Ewk_View_Smart_Data* pointer = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(ewkView))
381
382 #define EWK_VIEW_SD_GET_OR_RETURN(ewkView, pointer, ...) \
383     EWK_VIEW_TYPE_CHECK(ewkView, __VA_ARGS__); \
384     EWK_VIEW_SD_GET(ewkView, pointer); \
385     if (!pointer) { \
386         CRITICAL("no smart data for object %p (%s)", \
387                  ewkView, evas_object_type_get(ewkView)); \
388         return __VA_ARGS__; \
389     }
390
391 #define EWK_VIEW_PRIV_GET(smartData, pointer) \
392     Ewk_View_Private_Data* pointer = smartData->_priv
393
394 #define EWK_VIEW_PRIV_GET_OR_RETURN(smartData, pointer, ...) \
395     EWK_VIEW_PRIV_GET(smartData, pointer); \
396     if (!pointer) { \
397         CRITICAL("no private data for object %p (%s)", \
398                  smartData->self, evas_object_type_get(smartData->self)); \
399         return __VA_ARGS__; \
400     }
401
402 static void _ewk_view_smart_changed(Ewk_View_Smart_Data* smartData)
403 {
404     if (smartData->changed.any)
405         return;
406     smartData->changed.any = true;
407     evas_object_smart_changed(smartData->self);
408 }
409
410 // Default Event Handling //////////////////////////////////////////////
411 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
412 {
413     EWK_VIEW_PRIV_GET(smartData, priv);
414     WebCore::FocusController* focusController = &priv->page->focusController();
415     DBG("ewkView=%p, focusController=%p", smartData->self, focusController);
416
417     focusController->setActive(true);
418     focusController->setFocused(true);
419     return true;
420 }
421
422 static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* smartData)
423 {
424     EWK_VIEW_PRIV_GET(smartData, priv);
425     WebCore::FocusController* focusController = &priv->page->focusController();
426     DBG("ewkView=%p, fc=%p", smartData->self, focusController);
427
428     focusController->setActive(false);
429     focusController->setFocused(false);
430     return true;
431 }
432
433 static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
434 {
435     return ewk_frame_feed_mouse_wheel(smartData->main_frame, wheelEvent);
436 }
437
438 static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
439 {
440     return ewk_frame_feed_mouse_down(smartData->main_frame, downEvent);
441 }
442
443 static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
444 {
445     return ewk_frame_feed_mouse_up(smartData->main_frame, upEvent);
446 }
447
448 static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
449 {
450     return ewk_frame_feed_mouse_move(smartData->main_frame, moveEvent);
451 }
452
453 static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
454 {
455     Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
456
457     if (!frame)
458         frame = smartData->main_frame;
459
460     return ewk_frame_feed_key_down(frame, downEvent);
461 }
462
463 static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
464 {
465     Evas_Object* frame = ewk_view_frame_focused_get(smartData->self);
466
467     if (!frame)
468         frame = smartData->main_frame;
469
470     return ewk_frame_feed_key_up(frame, upEvent);
471 }
472
473 static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data*, const char* message, unsigned int lineNumber, const char* sourceID)
474 {
475     INFO("console message: %s @%d: %s\n", sourceID, lineNumber, message);
476 }
477
478 static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message)
479 {
480     INFO("javascript alert: %s\n", message);
481 }
482
483 static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message)
484 {
485     INFO("javascript confirm: %s", message);
486     INFO("javascript confirm (HARD CODED)? YES");
487     return true;
488 }
489
490 static Eina_Bool _ewk_view_smart_run_before_unload_confirm(Ewk_View_Smart_Data*, Evas_Object* /*frame*/, const char* message)
491 {
492     INFO("before unload confirm: %s", message);
493     return true;
494 }
495
496 static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data*)
497 {
498     INFO("should interrupt javascript?\n"
499         "\t(HARD CODED) NO");
500     return false;
501 }
502
503 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)
504 {
505     *value = eina_stringshare_add("test");
506     Eina_Bool result = true;
507     INFO("javascript prompt:\n"
508         "\t      message: %s\n"
509         "\tdefault value: %s\n"
510         "\tgiving answer: %s\n"
511         "\t       button: %s", message, defaultValue, *value, result ? "ok" : "cancel");
512
513     return result;
514 }
515
516 // Event Handling //////////////////////////////////////////////////////
517 static void _ewk_view_on_focus_in(void* data, Evas*, Evas_Object*, void*)
518 {
519     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
520     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
521     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_in);
522     smartData->api->focus_in(smartData);
523 }
524
525 static void _ewk_view_on_focus_out(void* data, Evas*, Evas_Object*, void*)
526 {
527     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
528     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
529     EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_out);
530     smartData->api->focus_out(smartData);
531 }
532
533 static void _ewk_view_on_mouse_wheel(void* data, Evas*, Evas_Object*, void* eventInfo)
534 {
535     Evas_Event_Mouse_Wheel* wheelEvent = static_cast<Evas_Event_Mouse_Wheel*>(eventInfo);
536     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
537     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
538     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_wheel);
539     smartData->api->mouse_wheel(smartData, wheelEvent);
540 }
541
542 static void _ewk_view_on_mouse_down(void* data, Evas*, Evas_Object*, void* eventInfo)
543 {
544     Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
545     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
546     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
547     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_down);
548     smartData->api->mouse_down(smartData, downEvent);
549 }
550
551 static void _ewk_view_on_mouse_up(void* data, Evas*, Evas_Object*, void* eventInfo)
552 {
553     Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
554     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
555     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
556     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_up);
557     smartData->api->mouse_up(smartData, upEvent);
558 }
559
560 static void _ewk_view_on_mouse_move(void* data, Evas*, Evas_Object*, void* eventInfo)
561 {
562     Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
563     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
564     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
565     EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_move);
566     smartData->api->mouse_move(smartData, moveEvent);
567 }
568
569 static void _ewk_view_on_key_down(void* data, Evas*, Evas_Object*, void* eventInfo)
570 {
571     Evas_Event_Key_Down* downEvent = static_cast<Evas_Event_Key_Down*>(eventInfo);
572     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
573     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
574     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_down);
575     smartData->api->key_down(smartData, downEvent);
576 }
577
578 static void _ewk_view_on_key_up(void* data, Evas*, Evas_Object*, void* eventInfo)
579 {
580     Evas_Event_Key_Up* upEvent = static_cast<Evas_Event_Key_Up*>(eventInfo);
581     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
582     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
583     EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_up);
584     smartData->api->key_up(smartData, upEvent);
585 }
586
587 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
588
589 static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData)
590 {
591     Ewk_View_Private_Data* priv = new Ewk_View_Private_Data;
592     memset(priv, 0, sizeof(Ewk_View_Private_Data));
593     AtomicString string;
594     WebCore::URL url;
595
596     WebCore::Page::PageClients pageClients;
597     pageClients.chromeClient = new WebCore::ChromeClientEfl(smartData->self);
598 #if ENABLE(CONTEXT_MENUS)
599     pageClients.contextMenuClient = new WebCore::ContextMenuClientEfl;
600 #endif
601     pageClients.editorClient = new WebCore::EditorClientEfl(smartData->self);
602     pageClients.dragClient = new WebCore::DragClientEfl;
603 #if ENABLE(INSPECTOR)
604     pageClients.inspectorClient = new WebCore::InspectorClientEfl(smartData->self);
605 #endif
606     pageClients.loaderClientForMainFrame = new WebCore::FrameLoaderClientEfl(smartData->self);
607     pageClients.progressTrackerClient = new WebCore::ProgressTrackerClientEfl(smartData->self);
608     priv->page = adoptPtr(new WebCore::Page(pageClients));
609
610 #if ENABLE(DEVICE_ORIENTATION)
611     WebCore::provideDeviceMotionTo(priv->page.get(), new WebCore::DeviceMotionClientEfl);
612     WebCore::provideDeviceOrientationTo(priv->page.get(), new WebCore::DeviceOrientationClientEfl);
613 #endif
614
615 #if ENABLE(VIBRATION)
616     WebCore::provideVibrationTo(priv->page.get(), new WebCore::VibrationClientEfl(smartData->self));
617 #endif
618
619 #if ENABLE(BATTERY_STATUS)
620     WebCore::provideBatteryTo(priv->page.get(), new BatteryClientEfl(smartData->self));
621 #endif
622
623 #if ENABLE(NAVIGATOR_CONTENT_UTILS)
624     WebCore::provideNavigatorContentUtilsTo(priv->page.get(), std::make_unique<WebCore::NavigatorContentUtilsClientEfl>(smartData->self));
625 #endif
626
627 #if ENABLE(GEOLOCATION)
628     if (DumpRenderTreeSupportEfl::dumpRenderTreeModeEnabled()) {
629         WebCore::GeolocationClientMock* mock = new WebCore::GeolocationClientMock;
630         WebCore::provideGeolocationTo(priv->page.get(), mock);
631         mock->setController(WebCore::GeolocationController::from(priv->page.get()));
632     }
633 #endif
634
635     WebCore::Settings& pageSettings = priv->page->settings();
636
637     WebCore::LayoutMilestones layoutMilestones = WebCore::DidFirstLayout | WebCore::DidFirstVisuallyNonEmptyLayout;
638     priv->page->addLayoutMilestones(layoutMilestones);
639
640     // FIXME: Noone is supposed to do this manually.
641     priv->viewportArguments.width = WebCore::ViewportArguments::ValueAuto;
642     priv->viewportArguments.height = WebCore::ViewportArguments::ValueAuto;
643     priv->viewportArguments.zoom = WebCore::ViewportArguments::ValueAuto;
644     priv->viewportArguments.minZoom = WebCore::ViewportArguments::ValueAuto;
645     priv->viewportArguments.maxZoom = WebCore::ViewportArguments::ValueAuto;
646     priv->viewportArguments.userZoom = true;
647
648     pageSettings.setLoadsImagesAutomatically(true);
649     pageSettings.setDefaultTextEncodingName("iso-8859-1");
650     pageSettings.setDefaultFixedFontSize(12);
651     pageSettings.setDefaultFontSize(16);
652     pageSettings.setSerifFontFamily("serif");
653     pageSettings.setFixedFontFamily("monotype");
654     pageSettings.setSansSerifFontFamily("sans");
655     pageSettings.setStandardFontFamily("sans");
656     pageSettings.setHyperlinkAuditingEnabled(false);
657     WebCore::RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(true);
658     pageSettings.setScriptEnabled(true);
659     pageSettings.setPluginsEnabled(true);
660     pageSettings.setLocalStorageEnabled(true);
661     pageSettings.setOfflineWebApplicationCacheEnabled(true);
662     pageSettings.setUsesPageCache(true);
663     pageSettings.setUsesEncodingDetector(false);
664 #if ENABLE(WEB_AUDIO)
665     pageSettings.setWebAudioEnabled(false);
666 #endif
667     pageSettings.setWebGLEnabled(true);
668     pageSettings.setXSSAuditorEnabled(true);
669 #if ENABLE(FULLSCREEN_API)
670     pageSettings.setFullScreenEnabled(true);
671 #endif
672     pageSettings.setInteractiveFormValidationEnabled(true);
673     pageSettings.setAcceleratedCompositingEnabled(true);
674     pageSettings.setForceCompositingMode(true);
675     char* debugVisualsEnvironment = getenv("WEBKIT_SHOW_COMPOSITING_DEBUG_VISUALS");
676     bool showDebugVisuals = debugVisualsEnvironment && !strcmp(debugVisualsEnvironment, "1");
677     pageSettings.setShowDebugBorders(showDebugVisuals);
678     pageSettings.setShowRepaintCounter(showDebugVisuals);
679
680     url = pageSettings.userStyleSheetLocation();
681     priv->settings.userStylesheet = eina_stringshare_add(url.string().utf8().data());
682
683     priv->settings.encodingDefault = eina_stringshare_add(pageSettings.defaultTextEncodingName().utf8().data());
684     priv->settings.encodingCustom = 0;
685
686     string = pageSettings.localStorageDatabasePath();
687     priv->settings.localStorageDatabasePath = eina_stringshare_add(string.string().utf8().data());
688
689     priv->settings.fontMinimumSize = pageSettings.minimumFontSize();
690     priv->settings.fontMinimumLogicalSize = pageSettings.minimumLogicalFontSize();
691     priv->settings.fontDefaultSize = pageSettings.defaultFontSize();
692     priv->settings.fontMonospaceSize = pageSettings.defaultFixedFontSize();
693
694     string = pageSettings.standardFontFamily();
695     priv->settings.fontStandard = eina_stringshare_add(string.string().utf8().data());
696     string = pageSettings.cursiveFontFamily();
697     priv->settings.fontCursive = eina_stringshare_add(string.string().utf8().data());
698     string = pageSettings.fixedFontFamily();
699     priv->settings.fontMonospace = eina_stringshare_add(string.string().utf8().data());
700     string = pageSettings.fantasyFontFamily();
701     priv->settings.fontFantasy = eina_stringshare_add(string.string().utf8().data());
702     string = pageSettings.serifFontFamily();
703     priv->settings.fontSerif = eina_stringshare_add(string.string().utf8().data());
704     string = pageSettings.sansSerifFontFamily();
705     priv->settings.fontSansSerif = eina_stringshare_add(string.string().utf8().data());
706
707     priv->settings.autoLoadImages = pageSettings.loadsImagesAutomatically();
708     priv->settings.autoShrinkImages = pageSettings.shrinksStandaloneImagesToFit();
709     priv->settings.enableAutoResizeWindow = true;
710     priv->settings.enableDeveloperExtras = pageSettings.developerExtrasEnabled();
711     priv->settings.enableScripts = pageSettings.isScriptEnabled();
712     priv->settings.enablePlugins = pageSettings.arePluginsEnabled();
713     priv->settings.enableFrameFlattening = pageSettings.frameFlatteningEnabled();
714 #if ENABLE(FULLSCREEN_API)
715     priv->settings.enableFullscreen = pageSettings.fullScreenEnabled();
716 #endif
717     priv->settings.enableXSSAuditor = pageSettings.xssAuditorEnabled();
718     priv->settings.hyperlinkAuditingEnabled = pageSettings.hyperlinkAuditingEnabled();
719     priv->settings.scriptsCanOpenWindows = pageSettings.javaScriptCanOpenWindowsAutomatically();
720     priv->settings.scriptsCanCloseWindows = pageSettings.allowScriptsToCloseWindows();
721 #if ENABLE(VIDEO_TRACK)
722     priv->settings.shouldDisplayCaptions = pageSettings.shouldDisplayCaptions();
723     priv->settings.shouldDisplaySubtitles = pageSettings.shouldDisplaySubtitles();
724     priv->settings.shouldDisplayTextDescriptions = pageSettings.shouldDisplayTextDescriptions();
725 #endif
726     priv->settings.scriptsCanAccessClipboard = pageSettings.javaScriptCanAccessClipboard() && pageSettings.DOMPasteAllowed();
727     priv->settings.resizableTextareas = pageSettings.textAreasAreResizable();
728     priv->settings.privateBrowsing = priv->page->usesEphemeralSession();
729     priv->settings.caretBrowsing = pageSettings.caretBrowsingEnabled();
730     priv->settings.spatialNavigation = pageSettings.spatialNavigationEnabled();
731     priv->settings.localStorage = pageSettings.localStorageEnabled();
732     priv->settings.offlineAppCache = true; // XXX no function to read setting; this keeps the original setting
733     priv->settings.pageCache = pageSettings.usesPageCache();
734     priv->settings.encodingDetector = pageSettings.usesEncodingDetector();
735     priv->settings.webGLEnabled = pageSettings.webGLEnabled();
736     priv->settings.tabsToLinks = true;
737
738     priv->settings.userAgent = ewk_settings_default_user_agent_get();
739
740     // Since there's no scale separated from zooming in webkit-efl, this functionality of
741     // viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl,
742     // this functionality will be modified by the scale zoom patch.
743     priv->settings.zoomRange.minScale = zoomMinimum;
744     priv->settings.zoomRange.maxScale = zoomMaximum;
745     priv->settings.zoomRange.userScalable = true;
746
747     priv->settings.domTimerInterval = pageSettings.defaultMinDOMTimerInterval();
748
749     priv->settings.allowUniversalAccessFromFileURLs = pageSettings.allowUniversalAccessFromFileURLs();
750     priv->settings.allowFileAccessFromFileURLs = pageSettings.allowFileAccessFromFileURLs();
751
752     priv->history = ewk_history_new(static_cast<WebCore::BackForwardList*>(priv->page->backForward().client()));
753
754 #if ENABLE(CONTEXT_MENUS)
755     priv->contextMenu = 0;
756 #endif
757
758     return priv;
759 }
760
761 static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
762 {
763     if (!priv)
764         return;
765
766     /* do not delete priv->main_frame */
767
768     eina_stringshare_del(priv->settings.userAgent);
769     eina_stringshare_del(priv->settings.userStylesheet);
770     eina_stringshare_del(priv->settings.encodingDefault);
771     eina_stringshare_del(priv->settings.encodingCustom);
772     eina_stringshare_del(priv->settings.fontStandard);
773     eina_stringshare_del(priv->settings.fontCursive);
774     eina_stringshare_del(priv->settings.fontMonospace);
775     eina_stringshare_del(priv->settings.fontFantasy);
776     eina_stringshare_del(priv->settings.fontSerif);
777     eina_stringshare_del(priv->settings.fontSansSerif);
778     eina_stringshare_del(priv->settings.localStorageDatabasePath);
779
780     if (priv->animatedZoom.animator)
781         ecore_animator_del(priv->animatedZoom.animator);
782
783     ewk_history_free(priv->history);
784
785     if (priv->cursorObject)
786         evas_object_del(priv->cursorObject);
787
788 #if ENABLE(CONTEXT_MENUS)
789     if (priv->contextMenu)
790         ewk_context_menu_free(priv->contextMenu);
791 #endif
792
793     priv->acceleratedCompositingContext = nullptr;
794
795     delete priv;
796 }
797
798 static void _ewk_view_accelerated_compositing_cb(void* data, Evas_Object*)
799 {
800     static_cast<WebCore::AcceleratedCompositingContext*>(data)->flushAndRenderLayers();
801 }
802
803 static void _ewk_view_smart_add(Evas_Object* ewkView)
804 {
805     const Evas_Smart* smart = evas_object_smart_smart_get(ewkView);
806     const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
807     const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
808     EWK_VIEW_SD_GET(ewkView, smartData);
809
810     if (!smartData) {
811         smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
812         if (!smartData) {
813             CRITICAL("could not allocate Ewk_View_Smart_Data");
814             return;
815         }
816         evas_object_smart_data_set(ewkView, smartData);
817     }
818
819     smartData->bg_color.r = 255;
820     smartData->bg_color.g = 255;
821     smartData->bg_color.b = 255;
822     smartData->bg_color.a = 255;
823
824     smartData->self = ewkView;
825     smartData->api = api;
826
827     _parent_sc.add(ewkView);
828
829     smartData->_priv = _ewk_view_priv_new(smartData);
830     if (!smartData->_priv)
831         return;
832
833     EWK_VIEW_PRIV_GET(smartData, priv);
834
835     smartData->image = evas_object_image_add(smartData->base.evas);
836     if (EINA_UNLIKELY(!smartData->image)) {
837         ERR("Could not create backing store object.");
838         return;
839     }
840
841     evas_object_image_alpha_set(smartData->image, false);
842     evas_object_image_filled_set(smartData->image, true);
843     evas_object_image_smooth_scale_set(smartData->image, smartData->zoom_weak_smooth_scale);
844     evas_object_pass_events_set(smartData->image, true);
845     evas_object_smart_member_add(smartData->image, ewkView);
846     evas_object_show(smartData->image);
847
848     priv->acceleratedCompositingContext = std::make_unique<WebCore::AcceleratedCompositingContext>(ewkView, smartData->image);
849
850     // Set the pixel get callback.
851     evas_object_image_pixels_get_callback_set(smartData->image, _ewk_view_accelerated_compositing_cb, priv->acceleratedCompositingContext.get());
852
853     smartData->events_rect = evas_object_rectangle_add(smartData->base.evas);
854     evas_object_color_set(smartData->events_rect, 0, 0, 0, 0);
855     evas_object_smart_member_add(smartData->events_rect, ewkView);
856     evas_object_show(smartData->events_rect);
857
858     smartData->main_frame = ewk_frame_add(smartData->base.evas);
859     if (!smartData->main_frame) {
860         ERR("Could not create main frame object.");
861         return;
862     }
863
864     if (!ewk_frame_init(smartData->main_frame, ewkView, adoptPtr(static_cast<WebCore::FrameLoaderClientEfl*>(&priv->page->mainFrame().loader().client())))) {
865         ERR("Could not initialize main frme object.");
866         evas_object_del(smartData->main_frame);
867         smartData->main_frame = 0;
868
869         return;
870     }
871     EWKPrivate::setCoreFrame(smartData->main_frame, &priv->page->mainFrame());
872     priv->page->mainFrame().tree().setName(String());
873     priv->page->mainFrame().init();
874
875     evas_object_name_set(smartData->main_frame, "EWK_Frame:main");
876     evas_object_smart_member_add(smartData->main_frame, ewkView);
877     evas_object_show(smartData->main_frame);
878
879 #define CONNECT(s, c) evas_object_event_callback_add(ewkView, s, c, smartData)
880     CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
881     CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
882     CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
883     CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down);
884     CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up);
885     CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move);
886     CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
887     CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
888 #undef CONNECT
889 }
890
891 static void _ewk_view_smart_del(Evas_Object* ewkView)
892 {
893     EWK_VIEW_SD_GET(ewkView, smartData);
894     Ewk_View_Private_Data* priv = smartData ? smartData->_priv : 0;
895
896     ewk_view_stop(ewkView);
897     _parent_sc.del(ewkView);
898     _ewk_view_priv_del(priv);
899 }
900
901 static void _ewk_view_smart_resize(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
902 {
903     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
904     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
905
906     // these should be queued and processed in calculate as well!
907     evas_object_resize(smartData->image, width, height);
908     evas_object_image_size_set(smartData->image, width, height);
909     evas_object_image_fill_set(smartData->image, 0, 0, width, height);
910
911     priv->acceleratedCompositingContext->resize(WebCore::IntSize(width, height));
912
913     smartData->changed.size = true;
914     _ewk_view_smart_changed(smartData);
915 }
916
917 static void _ewk_view_smart_move(Evas_Object* ewkView, Evas_Coord /*x*/, Evas_Coord /*y*/)
918 {
919     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
920     smartData->changed.position = true;
921     _ewk_view_smart_changed(smartData);
922 }
923
924 static inline void _ewk_view_screen_move(uint32_t* image, size_t destinationX, size_t destinationY, size_t sourceX, size_t sourceY, size_t copyWidth, size_t copyHeight, size_t imageWidth)
925 {
926     uint32_t* sourceBegin = image + (imageWidth * sourceY) + sourceX;
927     uint32_t* destinationBegin = image + (imageWidth * destinationY) + destinationX;
928
929     size_t copyLength = copyWidth * 4;
930
931     int moveLineUpDown;
932     int row;
933
934     if (sourceY >= destinationY) {
935         row = 0;
936         moveLineUpDown = 1;
937     } else {
938         row = copyHeight - 1;
939         moveLineUpDown = -1;
940     }
941
942     uint32_t* source, * destination;
943     if ((destinationX > sourceX && destinationX < sourceX + copyWidth)
944         || (destinationX < sourceX && destinationX + copyWidth > sourceX)) {
945         for (size_t i = 0; i < copyHeight; ++i, row += moveLineUpDown) {
946             source = sourceBegin + (imageWidth * row);
947             destination = destinationBegin + (imageWidth * row);
948             memmove(destination, source, copyLength);
949         }
950     } else {
951         for (size_t i = 0; i < copyHeight; ++i, row += moveLineUpDown) {
952             source = sourceBegin + (imageWidth * row);
953             destination = destinationBegin + (imageWidth * row);
954             memcpy(destination, source, copyLength);
955         }
956     }
957 }
958
959 static void _ewk_view_smart_calculate(Evas_Object* ewkView)
960 {
961     EWK_VIEW_SD_GET(ewkView, smartData);
962     EWK_VIEW_PRIV_GET(smartData, priv);
963     Evas_Coord x, y, width, height;
964
965     smartData->changed.any = false;
966
967     if (!smartData->main_frame)
968         return;
969
970     evas_object_geometry_get(ewkView, &x, &y, &width, &height);
971
972     DBG("ewkView=%p geo=[%d, %d + %dx%d], changed: size=%huu",
973         ewkView, x, y, width, height, smartData->changed.size);
974
975     if (smartData->changed.size && ((width != smartData->view.w) || (height != smartData->view.h))) {
976         WebCore::FrameView* view = priv->page->mainFrame().view();
977         if (view) {
978             view->resize(width, height);
979             view->forceLayout();
980             view->adjustViewSize();
981         }
982         evas_object_resize(smartData->main_frame, width, height);
983         evas_object_resize(smartData->events_rect, width, height);
984         smartData->changed.frame_rect = true;
985         smartData->view.w = width;
986         smartData->view.h = height;
987
988         // This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set).
989         evas_object_smart_callback_call(ewkView, "view,resized", 0);
990     }
991     smartData->changed.size = false;
992
993     if (smartData->changed.position && ((x != smartData->view.x) || (y != smartData->view.y))) {
994         evas_object_move(smartData->main_frame, x, y);
995         evas_object_move(smartData->image, x, y);
996         evas_object_move(smartData->events_rect, x, y);
997         smartData->changed.frame_rect = true;
998         smartData->view.x = x;
999         smartData->view.y = y;
1000     }
1001     smartData->changed.position = false;
1002
1003     if (smartData->changed.frame_rect) {
1004         priv->page->mainFrame().view()->frameRectsChanged();
1005         smartData->changed.frame_rect = false;
1006     }
1007 }
1008
1009 static void _ewk_view_smart_show(Evas_Object* ewkView)
1010 {
1011     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1012     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1013
1014     if (evas_object_clipees_get(smartData->base.clipper))
1015         evas_object_show(smartData->base.clipper);
1016     evas_object_show(smartData->image);
1017 }
1018
1019 static void _ewk_view_smart_hide(Evas_Object* ewkView)
1020 {
1021     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1022     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1023
1024     evas_object_hide(smartData->base.clipper);
1025     evas_object_hide(smartData->image);
1026 }
1027
1028 static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data*, int /*width*/, int /*height*/)
1029 {
1030     return true;
1031 }
1032
1033 static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1034 {
1035     double px, py;
1036     Evas_Coord x, y, width, height;
1037     Eina_Bool result;
1038
1039     ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
1040     ewk_frame_scroll_pos_get(smartData->main_frame, &x, &y);
1041
1042     if (width + smartData->view.w > 0)
1043         px = static_cast<double>(x + centerX) / (width + smartData->view.w);
1044     else
1045         px = 0.0;
1046
1047     if (height + smartData->view.h > 0)
1048         py = static_cast<double>(y + centerY) / (height + smartData->view.h);
1049     else
1050         py = 0.0;
1051
1052     result = ewk_frame_page_zoom_set(smartData->main_frame, zoom);
1053
1054     ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
1055     x = (width + smartData->view.w) * px - centerX;
1056     y = (height + smartData->view.h) * py - centerY;
1057     ewk_frame_scroll_set(smartData->main_frame, x, y);
1058     return result;
1059 }
1060
1061 static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* smartData)
1062 {
1063     smartData->animated_zoom.zoom.start = 0.0;
1064     smartData->animated_zoom.zoom.end = 0.0;
1065     smartData->animated_zoom.zoom.current = 0.0;
1066 }
1067
1068 static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* smartData)
1069 {
1070     EWK_VIEW_PRIV_GET(smartData, priv);
1071     ecore_animator_del(priv->animatedZoom.animator);
1072     priv->animatedZoom.animator = 0;
1073     _ewk_view_zoom_animated_mark_stop(smartData);
1074     evas_object_smart_callback_call(smartData->self, "zoom,animated,end", 0);
1075 }
1076
1077 static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv)
1078 {
1079     double now = ecore_loop_time_get();
1080     double delta = now - priv->animatedZoom.time.start;
1081
1082     if (delta > priv->animatedZoom.time.duration)
1083         delta = priv->animatedZoom.time.duration;
1084     if (delta < 0.0) // time went back, clock adjusted?
1085         delta = 0.0;
1086
1087     delta /= priv->animatedZoom.time.duration;
1088
1089     return ((priv->animatedZoom.zoom.range * delta)
1090             + priv->animatedZoom.zoom.start);
1091 }
1092
1093 static Eina_Bool _ewk_view_smart_zoom_weak_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1094 {
1095     float scale = zoom / smartData->animated_zoom.zoom.start;
1096     Evas_Coord w = smartData->view.w * scale;
1097     Evas_Coord h = smartData->view.h * scale;
1098     Evas_Coord deltaX, deltaY, contentWidth, contentHeight;
1099     Evas_Object* clip = evas_object_clip_get(smartData->image);
1100
1101     ewk_frame_contents_size_get(smartData->main_frame, &contentWidth, &contentHeight);
1102     if (smartData->view.w > 0 && smartData->view.h > 0) {
1103         deltaX = (w * (smartData->view.w - centerX)) / smartData->view.w;
1104         deltaY = (h * (smartData->view.h - centerY)) / smartData->view.h;
1105     } else {
1106         deltaX = 0;
1107         deltaY = 0;
1108     }
1109
1110     evas_object_image_fill_set(smartData->image, centerX + deltaX, centerY + deltaY, w, h);
1111
1112     if (smartData->view.w > 0 && smartData->view.h > 0) {
1113         deltaX = ((smartData->view.w - w) * centerX) / smartData->view.w;
1114         deltaY = ((smartData->view.h - h) * centerY) / smartData->view.h;
1115     } else {
1116         deltaX = 0;
1117         deltaY = 0;
1118     }
1119     evas_object_move(clip, smartData->view.x + deltaX, smartData->view.y + deltaY);
1120
1121     if (contentWidth < smartData->view.w)
1122         w = contentWidth * scale;
1123     if (contentHeight < smartData->view.h)
1124         h = contentHeight * scale;
1125     evas_object_resize(clip, w, h);
1126
1127     return true;
1128 }
1129
1130 static void _ewk_view_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data* smartData, Eina_Bool smooth_scale)
1131 {
1132     evas_object_image_smooth_scale_set(smartData->image, smooth_scale);
1133 }
1134
1135 static Eina_Bool _ewk_view_zoom_animator_cb(void* data)
1136 {
1137     Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
1138     Evas_Coord centerX, centerY;
1139     EWK_VIEW_PRIV_GET(smartData, priv);
1140     double now = ecore_loop_time_get();
1141
1142     centerX = priv->animatedZoom.center.x;
1143     centerY = priv->animatedZoom.center.y;
1144
1145     // TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2)
1146     if (centerX >= smartData->view.w)
1147         centerX = smartData->view.w - 1;
1148     if (centerY >= smartData->view.h)
1149         centerY = smartData->view.h - 1;
1150
1151     if ((now >= priv->animatedZoom.time.end)
1152         || (now < priv->animatedZoom.time.start)) {
1153         _ewk_view_zoom_animated_finish(smartData);
1154         ewk_view_zoom_set(smartData->self, priv->animatedZoom.zoom.end, centerX, centerY);
1155         smartData->api->sc.calculate(smartData->self);
1156         return false;
1157     }
1158
1159     smartData->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv);
1160     smartData->api->zoom_weak_set(smartData, smartData->animated_zoom.zoom.current, centerX, centerY);
1161     return true;
1162 }
1163
1164 static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* smartData)
1165 {
1166     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1167     if (priv->animatedZoom.animator)
1168         return;
1169     priv->animatedZoom.animator = ecore_animator_add
1170                                        (_ewk_view_zoom_animator_cb, smartData);
1171 }
1172
1173 static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(Ewk_View_Private_Data* priv)
1174 {
1175     int desktopWidth = 980;
1176     WebCore::IntRect availableRect = enclosingIntRect(priv->page->chrome().client().pageRect());
1177     WebCore::IntRect deviceRect = enclosingIntRect(priv->page->chrome().client().windowRect());
1178
1179     WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewportArguments, desktopWidth, deviceRect.width(), deviceRect.height(), priv->page->deviceScaleFactor(), availableRect.size());
1180     WebCore::restrictMinimumScaleFactorToViewportSize(attributes, availableRect.size(), priv->page->deviceScaleFactor());
1181     WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
1182
1183     return attributes;
1184 }
1185
1186 static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data* smartData)
1187 {
1188     WARN("not supported by engine. smartData=%p", smartData);
1189     return false;
1190 }
1191
1192 static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data* smartData)
1193 {
1194     WARN("not supported by engine. smartData=%p", smartData);
1195     return false;
1196 }
1197
1198 static const char* _ewk_view_editor_command_string_get(Ewk_View_Private_Data*, Ewk_Editor_Command ewkCommand)
1199 {
1200     static EflUniquePtr<Eina_Hash> editorCommandHash;
1201
1202     if (!editorCommandHash) {
1203         editorCommandHash = EflUniquePtr<Eina_Hash>(eina_hash_int32_new(0));
1204         for (int i = 0; editorCommands[i].ewkEditorCommand != EWK_EDITOR_COMMAND_NONE; i++)
1205             eina_hash_add(editorCommandHash.get(), &editorCommands[i].ewkEditorCommand, editorCommands[i].editorCommandString);
1206     }
1207     return reinterpret_cast<const char*>(eina_hash_find(editorCommandHash.get(), &ewkCommand));
1208 }
1209
1210 Eina_Bool ewk_view_smart_set(Ewk_View_Smart_Class* api)
1211 {
1212     EINA_SAFETY_ON_NULL_RETURN_VAL(api, false);
1213
1214     if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
1215         EINA_LOG_CRIT
1216             ("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
1217             api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
1218         return false;
1219     }
1220
1221     if (EINA_UNLIKELY(!_parent_sc.add))
1222         evas_object_smart_clipped_smart_set(&_parent_sc);
1223
1224     evas_object_smart_clipped_smart_set(&api->sc);
1225     api->sc.add = _ewk_view_smart_add;
1226     api->sc.del = _ewk_view_smart_del;
1227     api->sc.resize = _ewk_view_smart_resize;
1228     api->sc.move = _ewk_view_smart_move;
1229     api->sc.calculate = _ewk_view_smart_calculate;
1230     api->sc.show = _ewk_view_smart_show;
1231     api->sc.hide = _ewk_view_smart_hide;
1232     api->sc.data = ewkViewTypeString; /* used by type checking */
1233     api->sc.callbacks = _ewk_view_callback_names;
1234
1235     api->contents_resize = _ewk_view_smart_contents_resize;
1236     api->zoom_set = _ewk_view_smart_zoom_set;
1237     api->zoom_weak_set = _ewk_view_smart_zoom_weak_set;
1238     api->zoom_weak_smooth_scale_set = _ewk_view_smart_zoom_weak_smooth_scale_set;
1239     api->disable_render = _ewk_view_smart_disable_render;
1240     api->enable_render = _ewk_view_smart_enable_render;
1241
1242     api->focus_in = _ewk_view_smart_focus_in;
1243     api->focus_out = _ewk_view_smart_focus_out;
1244     api->mouse_wheel = _ewk_view_smart_mouse_wheel;
1245     api->mouse_down = _ewk_view_smart_mouse_down;
1246     api->mouse_up = _ewk_view_smart_mouse_up;
1247     api->mouse_move = _ewk_view_smart_mouse_move;
1248     api->key_down = _ewk_view_smart_key_down;
1249     api->key_up = _ewk_view_smart_key_up;
1250
1251     api->add_console_message = _ewk_view_smart_add_console_message;
1252     api->run_javascript_alert = _ewk_view_smart_run_javascript_alert;
1253     api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm;
1254     api->run_before_unload_confirm = _ewk_view_smart_run_before_unload_confirm;
1255     api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt;
1256     api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript;
1257
1258     return true;
1259 }
1260
1261 static inline Evas_Smart* _ewk_view_smart_class_new()
1262 {
1263     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(ewkViewTypeString);
1264     static Evas_Smart* smart = 0;
1265
1266     if (EINA_UNLIKELY(!smart)) {
1267         ewk_view_smart_set(&api);
1268         smart = evas_smart_class_new(&api.sc);
1269     }
1270
1271     return smart;
1272 }
1273
1274 Evas_Object* ewk_view_add(Evas* canvas)
1275 {
1276     return evas_object_smart_add(canvas, _ewk_view_smart_class_new());
1277 }
1278
1279 void ewk_view_fixed_layout_size_set(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
1280 {
1281     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1282     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1283
1284     WebCore::FrameView* view = priv->page->mainFrame().view();
1285     if (!view)
1286         return;
1287
1288     WebCore::IntSize layoutSize(width, height);
1289     if (layoutSize.width() <= 0 && layoutSize.height() <= 0) {
1290         if (!view->useFixedLayout())
1291             return;
1292         view->setUseFixedLayout(false);
1293     } else {
1294         WebCore::IntSize fixedLayoutSize = view->fixedLayoutSize();
1295         if (fixedLayoutSize == layoutSize)
1296             return;
1297         view->setFixedLayoutSize(layoutSize);
1298         view->setUseFixedLayout(true);
1299     }
1300
1301     view->setNeedsLayout();
1302 }
1303
1304 void ewk_view_fixed_layout_size_get(const Evas_Object* ewkView, Evas_Coord* width, Evas_Coord* height)
1305 {
1306     if (width)
1307         *width = 0;
1308     if (height)
1309         *height = 0;
1310     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1311     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1312     WebCore::FrameView* view = priv->page->mainFrame().view();
1313     if (view->useFixedLayout()) {
1314         WebCore::IntSize size = view->fixedLayoutSize();
1315         if (width)
1316             *width = size.width();
1317         if (height)
1318             *height = size.height();
1319     }
1320 }
1321
1322 void ewk_view_theme_set(Evas_Object* ewkView, const char* path)
1323 {
1324     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1325     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
1326     if (!eina_stringshare_replace(&priv->settings.theme, path))
1327         return;
1328
1329     WebCore::RenderThemeEfl& theme = static_cast<WebCore::RenderThemeEfl&>(priv->page->theme());
1330     theme.setThemePath(path);
1331 }
1332
1333 const char* ewk_view_theme_get(const Evas_Object* ewkView)
1334 {
1335     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1336     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1337     return priv->settings.theme;
1338 }
1339
1340 Evas_Object* ewk_view_frame_main_get(const Evas_Object* ewkView)
1341 {
1342     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1343     return smartData->main_frame;
1344 }
1345
1346 Evas_Object* ewk_view_frame_focused_get(const Evas_Object* ewkView)
1347 {
1348     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1349     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1350
1351     WebCore::Frame* core = priv->page->focusController().focusedFrame();
1352     if (!core)
1353         return 0;
1354
1355     WebCore::FrameLoaderClientEfl& client = static_cast<WebCore::FrameLoaderClientEfl&>(core->loader().client());
1356     return client.webFrame();
1357 }
1358
1359 Eina_Bool ewk_view_uri_set(Evas_Object* ewkView, const char* uri)
1360 {
1361     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1362     return ewk_frame_uri_set(smartData->main_frame, uri);
1363 }
1364
1365 const char* ewk_view_uri_get(const Evas_Object* ewkView)
1366 {
1367     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1368     return ewk_frame_uri_get(smartData->main_frame);
1369 }
1370
1371 const Ewk_Text_With_Direction* ewk_view_title_get(const Evas_Object* ewkView)
1372 {
1373     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1374     return ewk_frame_title_get(smartData->main_frame);
1375 }
1376
1377 Eina_Bool ewk_view_editable_get(const Evas_Object* ewkView)
1378 {
1379     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1380     return ewk_frame_editable_get(smartData->main_frame);
1381 }
1382
1383 void ewk_view_bg_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha)
1384 {
1385     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1386     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
1387
1388     if (alpha < 0) {
1389         WARN("Alpha less than zero (%d).", alpha);
1390         alpha = 0;
1391     } else if (alpha > 255) {
1392         WARN("Alpha is larger than 255 (%d).", alpha);
1393         alpha = 255;
1394     }
1395
1396 #define CHECK_PREMUL_COLOR(color, alpha)                                        \
1397     if (color < 0) {                                                        \
1398         WARN("Color component " #color " is less than zero (%d).", color);         \
1399         color = 0;                                                          \
1400     } else if (color > alpha) {                                                 \
1401         WARN("Color component " #color " is greater than alpha (%d, alpha=%d).", \
1402             color, alpha);                                                      \
1403         color = alpha;                                                          \
1404     }
1405     CHECK_PREMUL_COLOR(red, alpha);
1406     CHECK_PREMUL_COLOR(green, alpha);
1407     CHECK_PREMUL_COLOR(blue, alpha);
1408 #undef CHECK_PREMUL_COLOR
1409
1410     smartData->bg_color.r = red;
1411     smartData->bg_color.g = green;
1412     smartData->bg_color.b = blue;
1413     smartData->bg_color.a = alpha;
1414
1415     evas_object_image_alpha_set(smartData->image, alpha < 255);
1416
1417     WebCore::FrameView* view = smartData->_priv->page->mainFrame().view();
1418     if (view) {
1419         WebCore::Color color;
1420
1421         if (!alpha)
1422             color = WebCore::Color(0, 0, 0, 0);
1423         else if (alpha == 255)
1424             color = WebCore::Color(red, green, blue, alpha);
1425         else
1426             color = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
1427
1428         view->updateBackgroundRecursively(color, !alpha);
1429     }
1430 }
1431
1432 void ewk_view_bg_color_get(const Evas_Object* ewkView, int* red, int* green, int* blue, int* alpha)
1433 {
1434     if (red)
1435         *red = 0;
1436     if (green)
1437         *green = 0;
1438     if (blue)
1439         *blue = 0;
1440     if (alpha)
1441         *alpha = 0;
1442     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1443     if (red)
1444         *red = smartData->bg_color.r;
1445     if (green)
1446         *green = smartData->bg_color.g;
1447     if (blue)
1448         *blue = smartData->bg_color.b;
1449     if (alpha)
1450         *alpha = smartData->bg_color.a;
1451 }
1452
1453 Eina_Bool ewk_view_text_search(const Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
1454 {
1455     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1456     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1457     EINA_SAFETY_ON_NULL_RETURN_VAL(string, false);
1458
1459     WebCore::FindOptions options = (caseSensitive ? 0 : WebCore::CaseInsensitive) | (forward ? 0 : WebCore::Backwards) | (wrap ? WebCore::WrapAround : 0);
1460     return priv->page->findString(String::fromUTF8(string), options);
1461 }
1462
1463 /**
1464  * Mark matches the given text string in document.
1465  *
1466  * @param ewkView view object where to search text.
1467  * @param string reference string to match.
1468  * @param caseSensitive if match should be case sensitive or not.
1469  * @param heightighlight if matches should be highlighted.
1470  * @param limit maximum amount of matches, or zero to unlimited.
1471  *
1472  * @return number of matches.
1473  */
1474 unsigned int ewk_view_text_matches_mark(Evas_Object* ewkView, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
1475 {
1476     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1477     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1478     EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1479     WTF::TextCaseSensitivity sensitive;
1480
1481     if (caseSensitive)
1482         sensitive = WTF::TextCaseSensitive;
1483     else
1484         sensitive = WTF::TextCaseInsensitive;
1485
1486     return priv->page->markAllMatchesForText(String::fromUTF8(string), sensitive, highlight, limit);
1487 }
1488
1489 Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* ewkView)
1490 {
1491     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1492     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1493     priv->page->unmarkAllTextMatches();
1494     return true;
1495 }
1496
1497 Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* ewkView, Eina_Bool highlight)
1498 {
1499     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1500     return ewk_frame_text_matches_highlight_set(smartData->main_frame, highlight);
1501 }
1502
1503 Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* ewkView)
1504 {
1505     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1506     return ewk_frame_text_matches_highlight_get(smartData->main_frame);
1507 }
1508
1509 Eina_Bool ewk_view_editable_set(Evas_Object* ewkView, Eina_Bool editable)
1510 {
1511     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1512     return ewk_frame_editable_set(smartData->main_frame, editable);
1513 }
1514
1515 const char* ewk_view_selection_get(const Evas_Object* ewkView)
1516 {
1517     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1518     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1519     CString selectedString = priv->page->focusController().focusedOrMainFrame().editor().selectedText().utf8();
1520     if (selectedString.isNull())
1521         return 0;
1522     return eina_stringshare_add(selectedString.data());
1523 }
1524
1525 Eina_Bool ewk_view_editor_command_execute(const Evas_Object* ewkView, const Ewk_Editor_Command command, const char* value)
1526 {
1527     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1528     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1529
1530     const char* commandString = _ewk_view_editor_command_string_get(priv, command);
1531     if (!commandString)
1532         return false;
1533
1534     return priv->page->focusController().focusedOrMainFrame().editor().command(commandString).execute(WTF::String::fromUTF8(value));
1535 }
1536
1537 Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* ewkView, const Evas_Event_Mouse_Down* downEvent)
1538 {
1539 #if ENABLE(CONTEXT_MENUS)
1540     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1541     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1542     Eina_Bool mouse_press_handled = false;
1543
1544     priv->page->contextMenuController().clearContextMenu();
1545     if (priv->contextMenu)
1546         ewk_context_menu_free(priv->contextMenu);
1547
1548     WebCore::Frame& mainFrame = priv->page->mainFrame();
1549     Evas_Coord x, y;
1550     evas_object_geometry_get(smartData->self, &x, &y, 0, 0);
1551
1552     WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
1553
1554     if (mainFrame.view()) {
1555         mouse_press_handled =
1556             mainFrame.eventHandler().handleMousePressEvent(event);
1557     }
1558
1559     if (!mainFrame.eventHandler().sendContextMenuEvent(event))
1560         return false;
1561
1562     WebCore::ContextMenu* coreMenu =
1563         priv->page->contextMenuController().contextMenu();
1564     if (!coreMenu) {
1565         // WebCore decided not to create a context menu, return true if event
1566         // was handled by handleMouseReleaseEvent
1567         return mouse_press_handled;
1568     }
1569
1570     priv->contextMenu = ewk_context_menu_new(ewkView, &priv->page->contextMenuController(), coreMenu);
1571     if (!priv->contextMenu)
1572         return false;
1573
1574     ewk_context_menu_show(priv->contextMenu);
1575
1576     return true;
1577 #else
1578     UNUSED_PARAM(ewkView);
1579     UNUSED_PARAM(downEvent);
1580     return false;
1581 #endif
1582 }
1583
1584 double ewk_view_load_progress_get(const Evas_Object* ewkView)
1585 {
1586     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1587     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
1588     return priv->page->progress().estimatedProgress();
1589 }
1590
1591 Eina_Bool ewk_view_stop(Evas_Object* ewkView)
1592 {
1593     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1594     return ewk_frame_stop(smartData->main_frame);
1595 }
1596
1597 Eina_Bool ewk_view_reload(Evas_Object* ewkView)
1598 {
1599     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1600     return ewk_frame_reload(smartData->main_frame);
1601 }
1602
1603 Eina_Bool ewk_view_reload_full(Evas_Object* ewkView)
1604 {
1605     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1606     return ewk_frame_reload_full(smartData->main_frame);
1607 }
1608
1609 Eina_Bool ewk_view_back(Evas_Object* ewkView)
1610 {
1611     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1612     return ewk_frame_back(smartData->main_frame);
1613 }
1614
1615 Eina_Bool ewk_view_forward(Evas_Object* ewkView)
1616 {
1617     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1618     return ewk_frame_forward(smartData->main_frame);
1619 }
1620
1621 Eina_Bool ewk_view_navigate(Evas_Object* ewkView, int steps)
1622 {
1623     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1624     return ewk_frame_navigate(smartData->main_frame, steps);
1625 }
1626
1627 Eina_Bool ewk_view_back_possible(Evas_Object* ewkView)
1628 {
1629     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1630     return ewk_frame_back_possible(smartData->main_frame);
1631 }
1632
1633 Eina_Bool ewk_view_forward_possible(Evas_Object* ewkView)
1634 {
1635     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1636     return ewk_frame_forward_possible(smartData->main_frame);
1637 }
1638
1639 Eina_Bool ewk_view_navigate_possible(Evas_Object* ewkView, int steps)
1640 {
1641     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1642     return ewk_frame_navigate_possible(smartData->main_frame, steps);
1643 }
1644
1645 Eina_Bool ewk_view_history_enable_get(const Evas_Object* ewkView)
1646 {
1647     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1648     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1649     return static_cast<WebCore::BackForwardList*>(priv->page->backForward().client())->enabled();
1650 }
1651
1652 Eina_Bool ewk_view_history_enable_set(Evas_Object* ewkView, Eina_Bool enable)
1653 {
1654     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1655     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1656     static_cast<WebCore::BackForwardList*>(priv->page->backForward().client())->setEnabled(enable);
1657     return true;
1658 }
1659
1660 Ewk_History* ewk_view_history_get(const Evas_Object* ewkView)
1661 {
1662     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1663     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1664     if (!static_cast<WebCore::BackForwardList*>(priv->page->backForward().client())->enabled()) {
1665         ERR("asked history, but it's disabled! Returning 0!");
1666         return 0;
1667     }
1668     return priv->history;
1669 }
1670
1671 Eina_Bool ewk_view_visited_link_add(Evas_Object* ewkView, const char* visitedUrl)
1672 {
1673     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1674     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1675
1676     EINA_SAFETY_ON_NULL_RETURN_VAL(priv->page, false);
1677     EINA_SAFETY_ON_NULL_RETURN_VAL(priv->page->groupPtr(), false);
1678
1679     WebCore::URL kurl(WebCore::URL(), WTF::String::fromUTF8(visitedUrl));
1680     priv->page->groupPtr()->addVisitedLink(kurl);
1681     return true;
1682 }
1683
1684 float ewk_view_zoom_get(const Evas_Object* ewkView)
1685 {
1686     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1687     return ewk_frame_page_zoom_get(smartData->main_frame);
1688 }
1689
1690 Eina_Bool ewk_view_zoom_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1691 {
1692     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1693     EWK_VIEW_PRIV_GET(smartData, priv);
1694
1695     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
1696     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_set, false);
1697
1698     if (!priv->settings.zoomRange.userScalable) {
1699         WARN("userScalable is false");
1700         return false;
1701     }
1702
1703     if (zoom < priv->settings.zoomRange.minScale) {
1704         WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1705         return false;
1706     }
1707     if (zoom > priv->settings.zoomRange.maxScale) {
1708         WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1709         return false;
1710     }
1711
1712     _ewk_view_zoom_animated_mark_stop(smartData);
1713     return smartData->api->zoom_set(smartData, zoom, centerX, centerY);
1714 }
1715
1716 float ewk_view_page_zoom_get(const Evas_Object* ewkView)
1717 {
1718     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1719     return ewk_frame_page_zoom_get(smartData->main_frame);
1720 }
1721
1722 Eina_Bool ewk_view_page_zoom_set(Evas_Object* ewkView, float pageZoomFactor)
1723 {
1724     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1725     return ewk_frame_page_zoom_set(smartData->main_frame, pageZoomFactor);
1726 }
1727
1728 float ewk_view_scale_get(const Evas_Object* ewkView)
1729 {
1730     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1731     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
1732     return priv->page->pageScaleFactor();
1733 }
1734
1735 Eina_Bool ewk_view_scale_set(Evas_Object* ewkView, float scaleFactor, Evas_Coord scrollX, Evas_Coord scrollY)
1736 {
1737     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1738     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1739
1740     float currentScaleFactor = ewk_view_scale_get(ewkView);
1741     if (currentScaleFactor == -1)
1742         return false;
1743
1744     priv->page->setPageScaleFactor(scaleFactor, WebCore::IntPoint(scrollX, scrollY));
1745     return true;
1746 }
1747
1748 float ewk_view_text_zoom_get(const Evas_Object* ewkView)
1749 {
1750     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
1751     return ewk_frame_text_zoom_get(smartData->main_frame);
1752 }
1753
1754 Eina_Bool ewk_view_text_zoom_set(Evas_Object* ewkView, float textZoomFactor)
1755 {
1756     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1757     return ewk_frame_text_zoom_set(smartData->main_frame, textZoomFactor);
1758 }
1759
1760 Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* ewkView)
1761 {
1762     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1763     return smartData->zoom_weak_smooth_scale;
1764 }
1765
1766 void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* ewkView, Eina_Bool smoothScale)
1767 {
1768     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
1769     smoothScale = !!smoothScale;
1770     if (smartData->zoom_weak_smooth_scale == smoothScale)
1771         return;
1772     smartData->zoom_weak_smooth_scale = smoothScale;
1773     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
1774     EINA_SAFETY_ON_NULL_RETURN(smartData->api->zoom_weak_smooth_scale_set);
1775     smartData->api->zoom_weak_smooth_scale_set(smartData, smoothScale);
1776 }
1777
1778 Eina_Bool ewk_view_zoom_weak_set(Evas_Object* ewkView, float zoom, Evas_Coord centerX, Evas_Coord centerY)
1779 {
1780     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1781     EWK_VIEW_PRIV_GET(smartData, priv);
1782
1783     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
1784     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, false);
1785
1786     if (!priv->settings.zoomRange.userScalable) {
1787         WARN("userScalable is false");
1788         return false;
1789     }
1790
1791     if (zoom < priv->settings.zoomRange.minScale) {
1792         WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1793         return false;
1794     }
1795     if (zoom > priv->settings.zoomRange.maxScale) {
1796         WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1797         return false;
1798     }
1799
1800     smartData->animated_zoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
1801     smartData->animated_zoom.zoom.end = zoom;
1802     smartData->animated_zoom.zoom.current = zoom;
1803     return smartData->api->zoom_weak_set(smartData, zoom, centerX, centerY);
1804 }
1805
1806 Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* ewkView, float zoom)
1807 {
1808     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1809     smartData->animated_zoom.zoom.start = zoom;
1810     return true;
1811 }
1812
1813 Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* ewkView, float zoom)
1814 {
1815     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1816     smartData->animated_zoom.zoom.end = zoom;
1817     return true;
1818 }
1819
1820 Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* ewkView, float zoom)
1821 {
1822     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1823     smartData->animated_zoom.zoom.current = zoom;
1824     return true;
1825 }
1826
1827 Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* ewkView)
1828 {
1829     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1830     _ewk_view_zoom_animated_mark_stop(smartData);
1831     return true;
1832 }
1833
1834 Eina_Bool ewk_view_zoom_animated_set(Evas_Object* ewkView, float zoom, float duration, Evas_Coord centerX, Evas_Coord centerY)
1835 {
1836     double now;
1837     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1838     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1839     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
1840     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->zoom_weak_set, false);
1841
1842     if (!priv->settings.zoomRange.userScalable) {
1843         WARN("userScalable is false");
1844         return false;
1845     }
1846
1847     if (zoom < priv->settings.zoomRange.minScale) {
1848         WARN("zoom level is < %f : %f", priv->settings.zoomRange.minScale, zoom);
1849         return false;
1850     }
1851     if (zoom > priv->settings.zoomRange.maxScale) {
1852         WARN("zoom level is > %f : %f", priv->settings.zoomRange.maxScale, zoom);
1853         return false;
1854     }
1855
1856     if (priv->animatedZoom.animator)
1857         priv->animatedZoom.zoom.start = _ewk_view_zoom_animated_current(priv);
1858     else {
1859         priv->animatedZoom.zoom.start = ewk_frame_page_zoom_get(smartData->main_frame);
1860         _ewk_view_zoom_animation_start(smartData);
1861     }
1862
1863     if (centerX < 0)
1864         centerX = 0;
1865     if (centerY < 0)
1866         centerY = 0;
1867
1868     now = ecore_loop_time_get();
1869     priv->animatedZoom.time.start = now;
1870     priv->animatedZoom.time.end = now + duration;
1871     priv->animatedZoom.time.duration = duration;
1872     priv->animatedZoom.zoom.end = zoom;
1873     priv->animatedZoom.zoom.range = (priv->animatedZoom.zoom.end - priv->animatedZoom.zoom.start);
1874     priv->animatedZoom.center.x = centerX;
1875     priv->animatedZoom.center.y = centerY;
1876     smartData->animated_zoom.zoom.current = priv->animatedZoom.zoom.start;
1877     smartData->animated_zoom.zoom.start = priv->animatedZoom.zoom.start;
1878     smartData->animated_zoom.zoom.end = priv->animatedZoom.zoom.end;
1879
1880     return true;
1881 }
1882
1883 unsigned int ewk_view_imh_get(const Evas_Object* ewkView)
1884 {
1885     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1886     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1887     return priv->imh;
1888 }
1889
1890 Eina_Bool ewk_view_enable_render(const Evas_Object* ewkView)
1891 {
1892     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1893     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->enable_render, false);
1894     return smartData->api->enable_render(smartData);
1895 }
1896
1897 Eina_Bool ewk_view_disable_render(const Evas_Object* ewkView)
1898 {
1899     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1900     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api->disable_render, false);
1901     return smartData->api->disable_render(smartData);
1902 }
1903
1904 const char* ewk_view_setting_user_agent_get(const Evas_Object* ewkView)
1905 {
1906     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1907     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1908     return priv->settings.userAgent;
1909 }
1910
1911 Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* ewkView, const char* userAgent)
1912 {
1913     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1914     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1915     if (eina_stringshare_replace(&priv->settings.userAgent, userAgent)) {
1916         WebCore::FrameLoaderClientEfl& client = static_cast<WebCore::FrameLoaderClientEfl&>(priv->page->mainFrame().loader().client());
1917         client.setCustomUserAgent(String::fromUTF8(userAgent));
1918     }
1919     return true;
1920 }
1921
1922 const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* ewkView)
1923 {
1924     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
1925     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
1926     return priv->settings.userStylesheet;
1927 }
1928
1929 Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* ewkView, const char* uri)
1930 {
1931     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1932     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1933     if (eina_stringshare_replace(&priv->settings.userStylesheet, uri)) {
1934         WebCore::URL kurl(WebCore::URL(), String::fromUTF8(uri));
1935         priv->page->settings().setUserStyleSheetLocation(kurl);
1936     }
1937     return true;
1938 }
1939
1940 Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* ewkView)
1941 {
1942     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1943     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1944     return priv->settings.autoLoadImages;
1945 }
1946
1947 Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* ewkView, Eina_Bool automatic)
1948 {
1949     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1950     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1951     automatic = !!automatic;
1952     if (priv->settings.autoLoadImages != automatic) {
1953         priv->page->settings().setLoadsImagesAutomatically(automatic);
1954         priv->settings.autoLoadImages = automatic;
1955     }
1956     return true;
1957 }
1958
1959 Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* ewkView)
1960 {
1961     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1962     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1963     return priv->settings.autoShrinkImages;
1964 }
1965
1966 Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* ewkView, Eina_Bool automatic)
1967 {
1968     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1969     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1970     automatic = !!automatic;
1971     if (priv->settings.autoShrinkImages != automatic) {
1972         priv->page->settings().setShrinksStandaloneImagesToFit(automatic);
1973         priv->settings.autoShrinkImages = automatic;
1974     }
1975     return true;
1976 }
1977
1978 Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* ewkView)
1979 {
1980     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1981     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1982     return priv->settings.enableAutoResizeWindow;
1983 }
1984
1985 Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* ewkView, Eina_Bool resizable)
1986 {
1987     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1988     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1989     priv->settings.enableAutoResizeWindow = resizable;
1990     return true;
1991 }
1992
1993 Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* ewkView)
1994 {
1995     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
1996     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
1997     return priv->settings.enableScripts;
1998 }
1999
2000 Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* ewkView, Eina_Bool enable)
2001 {
2002     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2003     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2004     enable = !!enable;
2005     if (priv->settings.enableScripts != enable) {
2006         priv->page->settings().setScriptEnabled(enable);
2007         priv->settings.enableScripts = enable;
2008     }
2009     return true;
2010 }
2011
2012 Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* ewkView)
2013 {
2014     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2015     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2016     return priv->settings.enablePlugins;
2017 }
2018
2019 Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* ewkView, Eina_Bool enable)
2020 {
2021     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2022     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2023     enable = !!enable;
2024     if (priv->settings.enablePlugins != enable) {
2025         priv->page->settings().setPluginsEnabled(enable);
2026         priv->settings.enablePlugins = enable;
2027     }
2028     return true;
2029 }
2030
2031 Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* ewkView)
2032 {
2033     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2034     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2035     return priv->settings.enableFrameFlattening;
2036 }
2037
2038 Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* ewkView, Eina_Bool enable)
2039 {
2040     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2041     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2042     enable = !!enable;
2043     if (priv->settings.enableFrameFlattening != enable) {
2044         priv->page->settings().setFrameFlatteningEnabled(enable);
2045         priv->settings.enableFrameFlattening = enable;
2046     }
2047     return true;
2048 }
2049
2050 Eina_Bool ewk_view_setting_scripts_can_open_windows_get(const Evas_Object* ewkView)
2051 {
2052     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2053     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2054     return priv->settings.scriptsCanOpenWindows;
2055 }
2056
2057 Eina_Bool ewk_view_setting_scripts_can_open_windows_set(Evas_Object* ewkView, Eina_Bool allow)
2058 {
2059     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2060     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2061     allow = !!allow;
2062     if (priv->settings.scriptsCanOpenWindows != allow) {
2063         priv->page->settings().setJavaScriptCanOpenWindowsAutomatically(allow);
2064         priv->settings.scriptsCanOpenWindows = allow;
2065     }
2066     return true;
2067 }
2068
2069 Eina_Bool ewk_view_setting_scripts_can_close_windows_get(const Evas_Object* ewkView)
2070 {
2071     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2072     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2073     return priv->settings.scriptsCanCloseWindows;
2074 }
2075
2076 Eina_Bool ewk_view_setting_scripts_can_close_windows_set(Evas_Object* ewkView, Eina_Bool allow)
2077 {
2078     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2079     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2080     allow = !!allow;
2081     if (priv->settings.scriptsCanCloseWindows != allow) {
2082         priv->page->settings().setAllowScriptsToCloseWindows(allow);
2083         priv->settings.scriptsCanCloseWindows = allow;
2084     }
2085     return true;
2086 }
2087
2088 Eina_Bool ewk_view_setting_scripts_can_access_clipboard_get(const Evas_Object* ewkView)
2089 {
2090     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2091     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2092     return priv->settings.scriptsCanAccessClipboard;
2093 }
2094
2095 Eina_Bool ewk_view_setting_scripts_can_access_clipboard_set(Evas_Object* ewkView, Eina_Bool allow)
2096 {
2097     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2098     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2099     allow = !!allow;
2100     if (priv->settings.scriptsCanAccessClipboard != allow) {
2101         priv->page->settings().setJavaScriptCanAccessClipboard(allow);
2102         priv->page->settings().setDOMPasteAllowed(allow);
2103         priv->settings.scriptsCanAccessClipboard = allow;
2104     }
2105     return true;
2106 }
2107
2108 Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* ewkView)
2109 {
2110     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2111     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2112     return priv->settings.resizableTextareas;
2113 }
2114
2115 Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* ewkView, Eina_Bool enable)
2116 {
2117     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2118     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2119     enable = !!enable;
2120     if (priv->settings.resizableTextareas != enable) {
2121         priv->page->settings().setTextAreasAreResizable(enable);
2122         priv->settings.resizableTextareas = enable;
2123     }
2124     return true;
2125 }
2126
2127 Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* ewkView)
2128 {
2129     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2130     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2131     return priv->settings.privateBrowsing;
2132 }
2133
2134 Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
2135 {
2136     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2137     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2138     enable = !!enable;
2139     if (priv->settings.privateBrowsing != enable) {
2140         priv->page->enableLegacyPrivateBrowsing(enable);
2141         priv->settings.privateBrowsing = enable;
2142     }
2143     return true;
2144 }
2145
2146 Eina_Bool ewk_view_setting_application_cache_get(const Evas_Object* ewkView)
2147 {
2148     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2149     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2150     return priv->settings.offlineAppCache;
2151 }
2152
2153 Eina_Bool ewk_view_setting_application_cache_set(Evas_Object* ewkView, Eina_Bool enable)
2154 {
2155     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2156     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2157     enable = !!enable;
2158     if (priv->settings.offlineAppCache != enable) {
2159         priv->page->settings().setOfflineWebApplicationCacheEnabled(enable);
2160         priv->settings.offlineAppCache = enable;
2161     }
2162     return true;
2163 }
2164
2165 Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* ewkView)
2166 {
2167     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2168     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2169     return priv->settings.caretBrowsing;
2170 }
2171
2172 Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* ewkView, Eina_Bool enable)
2173 {
2174     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2175     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2176     enable = !!enable;
2177     if (priv->settings.caretBrowsing != enable) {
2178         priv->page->settings().setCaretBrowsingEnabled(enable);
2179         priv->settings.caretBrowsing = enable;
2180     }
2181     return true;
2182 }
2183
2184 const char* ewk_view_setting_encoding_custom_get(const Evas_Object* ewkView)
2185 {
2186     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2187     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2188     Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
2189     WebCore::Frame* core_frame = EWKPrivate::coreFrame(main_frame);
2190
2191     String overrideEncoding = core_frame->loader().documentLoader()->overrideEncoding();
2192
2193     if (overrideEncoding.isEmpty())
2194         return 0;
2195
2196     eina_stringshare_replace(&priv->settings.encodingCustom, overrideEncoding.utf8().data());
2197     return priv->settings.encodingCustom;
2198 }
2199
2200 Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* ewkView, const char* encoding)
2201 {
2202     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2203     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2204     Evas_Object* main_frame = ewk_view_frame_main_get(ewkView);
2205     WebCore::Frame* coreFrame = EWKPrivate::coreFrame(main_frame);
2206     DBG("%s", encoding);
2207     if (eina_stringshare_replace(&priv->settings.encodingCustom, encoding))
2208         coreFrame->loader().reloadWithOverrideEncoding(String::fromUTF8(encoding));
2209     return true;
2210 }
2211
2212 const char* ewk_view_setting_encoding_default_get(const Evas_Object* ewkView)
2213 {
2214     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2215     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2216     return priv->settings.encodingDefault;
2217 }
2218
2219 Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* ewkView, const char* encoding)
2220 {
2221     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2222     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2223     if (eina_stringshare_replace(&priv->settings.encodingDefault, encoding))
2224         priv->page->settings().setDefaultTextEncodingName(String::fromUTF8(encoding));
2225     return true;
2226 }
2227
2228 Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* ewkView, Eina_Bool enable)
2229 {
2230     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2231     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2232     enable = !!enable;
2233     if (priv->settings.encodingDetector != enable) {
2234         priv->page->settings().setUsesEncodingDetector(enable);
2235         priv->settings.encodingDetector = enable;
2236     }
2237     return true;
2238 }
2239
2240 Eina_Bool ewk_view_setting_encoding_detector_get(const Evas_Object* ewkView)
2241 {
2242     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2243     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2244     return priv->settings.encodingDetector;
2245 }
2246
2247 Eina_Bool ewk_view_setting_enable_developer_extras_get(const Evas_Object* ewkView)
2248 {
2249     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2250     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2251     return priv->settings.enableDeveloperExtras;
2252 }
2253
2254 Eina_Bool ewk_view_setting_enable_developer_extras_set(Evas_Object* ewkView, Eina_Bool enable)
2255 {
2256     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2257     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2258     enable = !!enable;
2259     if (priv->settings.enableDeveloperExtras != enable) {
2260         priv->page->settings().setDeveloperExtrasEnabled(enable);
2261         priv->settings.enableDeveloperExtras = enable;
2262     }
2263     return true;
2264 }
2265
2266 int ewk_view_setting_font_minimum_size_get(const Evas_Object* ewkView)
2267 {
2268     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2269     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2270     return priv->settings.fontMinimumSize;
2271 }
2272
2273 Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* ewkView, int size)
2274 {
2275     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2276     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2277     if (priv->settings.fontMinimumSize != size) {
2278         priv->page->settings().setMinimumFontSize(size);
2279         priv->settings.fontMinimumSize = size;
2280     }
2281     return true;
2282 }
2283
2284 int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* ewkView)
2285 {
2286     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2287     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2288     return priv->settings.fontMinimumLogicalSize;
2289 }
2290
2291 Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* ewkView, int size)
2292 {
2293     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2294     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2295     if (priv->settings.fontMinimumLogicalSize != size) {
2296         priv->page->settings().setMinimumLogicalFontSize(size);
2297         priv->settings.fontMinimumLogicalSize = size;
2298     }
2299     return true;
2300 }
2301
2302 int ewk_view_setting_font_default_size_get(const Evas_Object* ewkView)
2303 {
2304     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2305     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2306     return priv->settings.fontDefaultSize;
2307 }
2308
2309 Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object* ewkView, int size)
2310 {
2311     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2312     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2313     if (priv->settings.fontDefaultSize != size) {
2314         priv->page->settings().setDefaultFontSize(size);
2315         priv->settings.fontDefaultSize = size;
2316     }
2317     return true;
2318 }
2319
2320 int ewk_view_setting_font_monospace_size_get(const Evas_Object* ewkView)
2321 {
2322     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2323     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2324     return priv->settings.fontMonospaceSize;
2325 }
2326
2327 Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object* ewkView, int size)
2328 {
2329     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2330     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2331     if (priv->settings.fontMonospaceSize != size) {
2332         priv->page->settings().setDefaultFixedFontSize(size);
2333         priv->settings.fontMonospaceSize = size;
2334     }
2335     return true;
2336 }
2337
2338 const char* ewk_view_font_family_name_get(const Evas_Object* ewkView, Ewk_Font_Family fontFamily)
2339 {
2340     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2341     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2342
2343     switch (fontFamily) {
2344     case EWK_FONT_FAMILY_STANDARD:
2345         return priv->settings.fontStandard;
2346     case EWK_FONT_FAMILY_CURSIVE:
2347         return priv->settings.fontCursive;
2348     case EWK_FONT_FAMILY_FANTASY:
2349         return priv->settings.fontFantasy;
2350     case EWK_FONT_FAMILY_MONOSPACE:
2351         return priv->settings.fontMonospace;
2352     case EWK_FONT_FAMILY_SERIF:
2353         return priv->settings.fontSerif;
2354     case EWK_FONT_FAMILY_SANS_SERIF:
2355         return priv->settings.fontSansSerif;
2356     }
2357     return 0;
2358 }
2359
2360 Eina_Bool ewk_view_font_family_name_set(Evas_Object* ewkView, Ewk_Font_Family fontFamily, const char* name)
2361 {
2362     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2363     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2364
2365     switch (fontFamily) {
2366     case EWK_FONT_FAMILY_STANDARD:
2367         eina_stringshare_replace(&priv->settings.fontStandard, name);
2368         priv->page->settings().setStandardFontFamily(AtomicString::fromUTF8(name));
2369         break;
2370     case EWK_FONT_FAMILY_CURSIVE:
2371         eina_stringshare_replace(&priv->settings.fontCursive, name);
2372         priv->page->settings().setCursiveFontFamily(AtomicString::fromUTF8(name));
2373         break;
2374     case EWK_FONT_FAMILY_FANTASY:
2375         eina_stringshare_replace(&priv->settings.fontFantasy, name);
2376         priv->page->settings().setFantasyFontFamily(AtomicString::fromUTF8(name));
2377         break;
2378     case EWK_FONT_FAMILY_MONOSPACE:
2379         eina_stringshare_replace(&priv->settings.fontMonospace, name);
2380         priv->page->settings().setFixedFontFamily(AtomicString::fromUTF8(name));
2381         break;
2382     case EWK_FONT_FAMILY_SERIF:
2383         eina_stringshare_replace(&priv->settings.fontSerif, name);
2384         priv->page->settings().setSerifFontFamily(AtomicString::fromUTF8(name));
2385         break;
2386     case EWK_FONT_FAMILY_SANS_SERIF:
2387         eina_stringshare_replace(&priv->settings.fontSansSerif, name);
2388         priv->page->settings().setSansSerifFontFamily(AtomicString::fromUTF8(name));
2389         break;
2390     default:
2391         return false;
2392     }
2393
2394     return true;
2395 }
2396
2397 Eina_Bool ewk_view_setting_spatial_navigation_get(const Evas_Object* ewkView)
2398 {
2399     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2400     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2401     return priv->settings.spatialNavigation;
2402 }
2403
2404 Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* ewkView, Eina_Bool enable)
2405 {
2406     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2407     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2408     enable = !!enable;
2409     if (priv->settings.spatialNavigation != enable) {
2410         priv->page->settings().setSpatialNavigationEnabled(enable);
2411         priv->settings.spatialNavigation = enable;
2412     }
2413     return true;
2414 }
2415
2416 Eina_Bool ewk_view_setting_local_storage_get(const Evas_Object* ewkView)
2417 {
2418     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2419     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2420     return priv->settings.localStorage;
2421 }
2422
2423 Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* ewkView, Eina_Bool enable)
2424 {
2425     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2426     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2427     enable = !!enable;
2428     if (priv->settings.localStorage != enable) {
2429         priv->page->settings().setLocalStorageEnabled(enable);
2430         priv->settings.localStorage = enable;
2431     }
2432     return true;
2433 }
2434
2435 Eina_Bool ewk_view_setting_page_cache_get(const Evas_Object* ewkView)
2436 {
2437     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2438     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2439     return priv->settings.pageCache;
2440 }
2441
2442 Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* ewkView, Eina_Bool enable)
2443 {
2444     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2445     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2446     enable = !!enable;
2447     if (priv->settings.pageCache != enable) {
2448         priv->page->settings().setUsesPageCache(enable);
2449         priv->settings.pageCache = enable;
2450     }
2451     return true;
2452 }
2453
2454 const char* ewk_view_setting_local_storage_database_path_get(const Evas_Object* ewkView)
2455 {
2456     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2457     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
2458     return priv->settings.localStorageDatabasePath;
2459 }
2460
2461 Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object* ewkView, const char* path)
2462 {
2463     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2464     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2465     if (eina_stringshare_replace(&priv->settings.localStorageDatabasePath, path))
2466         priv->page->settings().setLocalStorageDatabasePath(String::fromUTF8(path));
2467     return true;
2468 }
2469
2470 Eina_Bool ewk_view_setting_minimum_timer_interval_set(Evas_Object* ewkView, double interval)
2471 {
2472     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2473     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2474     if (fabs(priv->settings.domTimerInterval - interval) >= std::numeric_limits<double>::epsilon()) {
2475         priv->page->settings().setMinDOMTimerInterval(interval);
2476         priv->settings.domTimerInterval = interval;
2477     }
2478     return true;
2479 }
2480
2481 double ewk_view_setting_minimum_timer_interval_get(const Evas_Object* ewkView)
2482 {
2483     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
2484     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
2485     return priv->settings.domTimerInterval;
2486 }
2487
2488 Eina_Bool ewk_view_setting_enable_webgl_get(const Evas_Object* ewkView)
2489 {
2490     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2491     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2492     return priv->settings.webGLEnabled;
2493 }
2494
2495 Eina_Bool ewk_view_setting_enable_webgl_set(Evas_Object* ewkView, Eina_Bool enable)
2496 {
2497     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2498     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2499     enable = !!enable;
2500     if (priv->settings.webGLEnabled != enable) {
2501         priv->page->settings().setWebGLEnabled(enable);
2502         priv->settings.webGLEnabled = enable;
2503     }
2504     return true;
2505 }
2506
2507 Eina_Bool ewk_view_setting_include_links_in_focus_chain_get(const Evas_Object* ewkView)
2508 {
2509     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2510     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2511     return priv->settings.tabsToLinks;
2512 }
2513
2514 Eina_Bool ewk_view_setting_include_links_in_focus_chain_set(Evas_Object* ewkView, Eina_Bool enable)
2515 {
2516     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2517     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2518     enable = !!enable;
2519     priv->settings.tabsToLinks = enable;
2520     return true;
2521 }
2522
2523 Eina_Bool ewk_view_setting_enable_hyperlink_auditing_get(const Evas_Object* ewkView)
2524 {
2525     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2526     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2527     return priv->settings.hyperlinkAuditingEnabled;
2528 }
2529
2530 Eina_Bool ewk_view_setting_enable_hyperlink_auditing_set(Evas_Object* ewkView, Eina_Bool enable)
2531 {
2532     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2533     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2534     enable = !!enable;
2535     if (priv->settings.hyperlinkAuditingEnabled != enable) {
2536         priv->page->settings().setHyperlinkAuditingEnabled(enable);
2537         priv->settings.hyperlinkAuditingEnabled = enable;
2538     }
2539     return true;
2540 }
2541
2542 Eina_Bool ewk_view_setting_allow_universal_access_from_file_urls_set(Evas_Object* ewkView, Eina_Bool enable)
2543 {
2544     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2545     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2546     enable = !!enable;
2547     if (priv->settings.allowUniversalAccessFromFileURLs != enable) {
2548         priv->page->settings().setAllowUniversalAccessFromFileURLs(enable);
2549         priv->settings.allowUniversalAccessFromFileURLs = enable;
2550     }
2551     return true;
2552 }
2553
2554 Eina_Bool ewk_view_setting_allow_universal_access_from_file_urls_get(const Evas_Object* ewkView)
2555 {
2556     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2557     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2558     return priv->settings.allowUniversalAccessFromFileURLs;
2559 }
2560
2561 Eina_Bool ewk_view_setting_allow_file_access_from_file_urls_set(Evas_Object* ewkView, Eina_Bool enable)
2562 {
2563     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2564     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2565     enable = !!enable;
2566     if (priv->settings.allowFileAccessFromFileURLs != enable) {
2567         priv->page->settings().setAllowFileAccessFromFileURLs(enable);
2568         priv->settings.allowFileAccessFromFileURLs = enable;
2569     }
2570     return true;
2571 }
2572
2573 Eina_Bool ewk_view_setting_allow_file_access_from_file_urls_get(const Evas_Object* ewkView)
2574 {
2575     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
2576     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
2577     return priv->settings.allowFileAccessFromFileURLs;
2578 }
2579
2580 Ewk_View_Smart_Data* ewk_view_smart_data_get(const Evas_Object* ewkView)
2581 {
2582     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2583     return smartData;
2584 }
2585
2586 /**
2587  * Do layout if required, applied recursively.
2588  *
2589  * @param priv private handle pointer of the view to layout.
2590  *
2591  * @note this is not for general use but just for subclasses that want
2592  *       to define their own backing store.
2593  */
2594 void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data* priv)
2595 {
2596     EINA_SAFETY_ON_NULL_RETURN(priv);
2597
2598     WebCore::FrameView* view = priv->page->mainFrame().view();
2599     if (!view) {
2600         ERR("no main frame view");
2601         return;
2602     }
2603     view->updateLayoutAndStyleIfNeededRecursive();
2604 }
2605
2606 /**
2607  * @internal
2608  * Reports the view is ready to be displayed as all elements are aready.
2609  *
2610  * Emits signal: "ready" with no parameters.
2611  */
2612 void ewk_view_ready(Evas_Object* ewkView)
2613 {
2614     DBG("ewkView=%p", ewkView);
2615     evas_object_smart_callback_call(ewkView, "ready", 0);
2616 }
2617
2618 /**
2619  * @internal
2620  * Reports the state of input method changed. This is triggered, for example
2621  * when a input field received/lost focus
2622  *
2623  * Emits signal: "inputmethod,changed" with a boolean indicating whether it's
2624  * enabled or not.
2625  */
2626 void ewk_view_input_method_state_set(Evas_Object* ewkView, bool active)
2627 {
2628     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2629     EWK_VIEW_PRIV_GET(smartData, priv);
2630     WebCore::Frame& focusedFrame = priv->page->focusController().focusedOrMainFrame();
2631
2632     priv->imh = 0;
2633     if (focusedFrame.document()
2634         && focusedFrame.document()->focusedElement()
2635         && isHTMLInputElement(focusedFrame.document()->focusedElement())) {
2636         WebCore::HTMLInputElement* inputElement;
2637
2638         inputElement = static_cast<WebCore::HTMLInputElement*>(focusedFrame.document()->focusedElement());
2639         if (inputElement) {
2640             // for password fields, active == false
2641             if (!active) {
2642                 active = inputElement->isPasswordField();
2643                 priv->imh = inputElement->isPasswordField() * EWK_IMH_PASSWORD;
2644             } else {
2645                 // Set input method hints for "number", "tel", "email", and "url" input elements.
2646                 priv->imh |= inputElement->isTelephoneField() * EWK_IMH_TELEPHONE;
2647                 priv->imh |= inputElement->isNumberField() * EWK_IMH_NUMBER;
2648                 priv->imh |= inputElement->isEmailField() * EWK_IMH_EMAIL;
2649                 priv->imh |= inputElement->isURLField() * EWK_IMH_URL;
2650             }
2651         }
2652     }
2653
2654     evas_object_smart_callback_call(ewkView, "inputmethod,changed", (void*)active);
2655 }
2656
2657 /**
2658  * @internal
2659  * The view title was changed by the frame loader.
2660  *
2661  * Emits signal: "title,changed" with pointer to new title string.
2662  */
2663 void ewk_view_title_set(Evas_Object* ewkView, const Ewk_Text_With_Direction* title)
2664 {
2665     DBG("ewkView=%p, title=%s", ewkView, (title && title->string) ? title->string : "(null)");
2666     evas_object_smart_callback_call(ewkView, "title,changed", (void*)title);
2667 }
2668
2669 /**
2670  * @internal
2671  * Reports that main frame's uri changed.
2672  *
2673  * Emits signal: "uri,changed" with pointer to the new uri string.
2674  */
2675 void ewk_view_uri_changed(Evas_Object* ewkView)
2676 {
2677     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2678     const char* uri = ewk_frame_uri_get(smartData->main_frame);
2679     DBG("ewkView=%p, uri=%s", ewkView, uri ? uri : "(null)");
2680     evas_object_smart_callback_call(ewkView, "uri,changed", (void*)uri);
2681 }
2682
2683 /**
2684  * @internal
2685  * Reports that a DOM document object has finished loading for @p frame.
2686  *
2687  * @param ewkView View which contains the frame.
2688  * @param frame The frame whose load has triggered the event.
2689  *
2690  * Emits signal: "load,document,finished" with @p frame as the parameter.
2691  */
2692 void ewk_view_load_document_finished(Evas_Object* ewkView, Evas_Object* frame)
2693 {
2694     evas_object_smart_callback_call(ewkView, "load,document,finished", frame);
2695 }
2696
2697 /**
2698  * @internal
2699  * Reports the view started loading something.
2700  *
2701  * @param ewkView View.
2702  * @param ewkFrame Frame being loaded.
2703  *
2704  * Emits signal: "load,started" with no parameters.
2705  */
2706 void ewk_view_load_started(Evas_Object* ewkView, Evas_Object* ewkFrame)
2707 {
2708     DBG("ewkView=%p, ewkFrame=%p", ewkView, ewkFrame);
2709     evas_object_smart_callback_call(ewkView, "load,started", ewkFrame);
2710 }
2711
2712 /**
2713  * Reports the frame started loading something.
2714  *
2715  * @param ewkView View.
2716  *
2717  * Emits signal: "load,started" on main frame with no parameters.
2718  */
2719 void ewk_view_frame_main_load_started(Evas_Object* ewkView)
2720 {
2721     DBG("ewkView=%p", ewkView);
2722     Evas_Object* frame = ewk_view_frame_main_get(ewkView);
2723     evas_object_smart_callback_call(frame, "load,started", 0);
2724 }
2725
2726 /**
2727  * @internal
2728  * Reports the main frame started provisional load.
2729  *
2730  * @param ewkView View.
2731  *
2732  * Emits signal: "load,provisional" on View with no parameters.
2733  */
2734 void ewk_view_load_provisional(Evas_Object* ewkView)
2735 {
2736     DBG("ewkView=%p", ewkView);
2737     evas_object_smart_callback_call(ewkView, "load,provisional", 0);
2738 }
2739
2740 /**
2741  * @internal
2742  * Reports the main frame provisional load failed.
2743  *
2744  * @param ewkView View.
2745  * @param error Load error.
2746  *
2747  * Emits signal: "load,provisional" on View with pointer to Ewk_Frame_Load_Error.
2748  */
2749 void ewk_view_load_provisional_failed(Evas_Object* ewkView, const Ewk_Frame_Load_Error* error)
2750 {
2751     DBG("ewkView=%p, error=%p", ewkView, error);
2752     evas_object_smart_callback_call(ewkView, "load,provisional,failed", const_cast<Ewk_Frame_Load_Error*>(error));
2753 }
2754
2755 /**
2756  * @internal
2757  * Reports view can be shown after a new window is created.
2758  *
2759  * @param ewkView Frame.
2760  *
2761  * Emits signal: "load,newwindow,show" on view with no parameters.
2762  */
2763 void ewk_view_load_show(Evas_Object* ewkView)
2764 {
2765     DBG("ewkView=%p", ewkView);
2766     evas_object_smart_callback_call(ewkView, "load,newwindow,show", 0);
2767 }
2768
2769 /**
2770  * @internal
2771  * Reports an onload event for @p frame.
2772  *
2773  * @param ewkView View which contains the frame.
2774  * @param frame The frame whose onload event was received.
2775  *
2776  * Emits signal: "onload,event" with @p frame as the parameter.
2777  */
2778 void ewk_view_onload_event(Evas_Object* ewkView, Evas_Object* frame)
2779 {
2780     evas_object_smart_callback_call(ewkView, "onload,event", frame);
2781 }
2782
2783 /**
2784  * @internal
2785  * Reports the main frame received an icon.
2786  *
2787  * @param ewkView View.
2788  *
2789  * Emits signal: "icon,received" with no parameters.
2790  */
2791 void ewk_view_frame_main_icon_received(Evas_Object* ewkView)
2792 {
2793     DBG("ewkView=%p", ewkView);
2794     Evas_Object* frame = ewk_view_frame_main_get(ewkView);
2795     evas_object_smart_callback_call(frame, "icon,received", 0);
2796 }
2797
2798 /**
2799  * @internal
2800  * Reports load finished, optionally with error information.
2801  *
2802  * Emits signal: "load,finished" with pointer to #Ewk_Frame_Load_Error
2803  * if any error, or @c 0 if successful load.
2804  *
2805  * @note there should not be any error stuff here, but trying to be
2806  *       compatible with previous WebKit.
2807  */
2808 void ewk_view_load_finished(Evas_Object* ewkView, const Ewk_Frame_Load_Error* error)
2809 {
2810     DBG("ewkView=%p, error=%p", ewkView, error);
2811     evas_object_smart_callback_call(ewkView, "load,finished", (void*)error);
2812 }
2813
2814 /**
2815  * @internal
2816  * Reports load failed with error information.
2817  *
2818  * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
2819  */
2820 void ewk_view_load_error(Evas_Object* ewkView, const Ewk_Frame_Load_Error* error)
2821 {
2822     DBG("ewkView=%p, error=%p", ewkView, error);
2823     evas_object_smart_callback_call(ewkView, "load,error", (void*)error);
2824 }
2825
2826 /**
2827  * @internal
2828  * Reports load progress changed.
2829  *
2830  * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
2831  */
2832 void ewk_view_load_progress_changed(Evas_Object* ewkView)
2833 {
2834     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2835     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
2836
2837     // Evas_Coord width, height;
2838     double progress = priv->page->progress().estimatedProgress();
2839
2840     DBG("ewkView=%p (p=%0.3f)", ewkView, progress);
2841
2842     evas_object_smart_callback_call(ewkView, "load,progress", &progress);
2843 }
2844
2845 /**
2846  * @internal
2847  * Reports view @param ewkView should be restored to default conditions
2848  *
2849  * @param ewkView View.
2850  * @param frame Frame that originated restore.
2851  *
2852  * Emits signal: "restore" with frame.
2853  */
2854 void ewk_view_restore_state(Evas_Object* ewkView, Evas_Object* frame)
2855 {
2856     evas_object_smart_callback_call(ewkView, "restore", frame);
2857 }
2858
2859 /**
2860  * @internal
2861  * Delegates to browser the creation of a new window. If it is not implemented,
2862  * current view is returned, so navigation might continue in same window. If
2863  * browser supports the creation of new windows, a new Ewk_Window_Features is
2864  * created and passed to browser. If it intends to keep the request for opening
2865  * the window later it must increments the Ewk_Winwdow_Features ref count by
2866  * calling ewk_window_features_ref(window_features). Otherwise this struct will
2867  * be freed after returning to this function.
2868  *
2869  * @param ewkView Current view.
2870  * @param javascript @c true if the new window is originated from javascript,
2871  * @c false otherwise
2872  * @param window_features Features of the new window being created. If it's @c
2873  * 0, it will be created a window with default features.
2874  *
2875  * @return New view, in case smart class implements the creation of new windows;
2876  * else, current view @param ewkView or @c 0 on failure.
2877  *
2878  * @see ewk_window_features_ref().
2879  */
2880 Evas_Object* ewk_view_window_create(Evas_Object* ewkView, bool javascript, const WebCore::WindowFeatures* coreFeatures)
2881 {
2882     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
2883
2884     if (!smartData->api->window_create)
2885         return ewkView;
2886
2887     Ewk_Window_Features* windowFeatures = ewk_window_features_new_from_core(coreFeatures);
2888     if (!windowFeatures)
2889         return 0;
2890
2891     Evas_Object* view = smartData->api->window_create(smartData, javascript, windowFeatures);
2892     ewk_window_features_unref(windowFeatures);
2893
2894     return view;
2895 }
2896
2897 /**
2898  * @internal
2899  * Reports a window should be closed. It's client responsibility to decide if
2900  * the window should in fact be closed. So, if only windows created by javascript
2901  * are allowed to be closed by this call, browser needs to save the javascript
2902  * flag when the window is created. Since a window can close itself (for example
2903  * with a 'self.close()' in Javascript) browser must postpone the deletion to an
2904  * idler.
2905  *
2906  * @param ewkView View to be closed.
2907  */
2908 void ewk_view_window_close(Evas_Object* ewkView)
2909 {
2910     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
2911
2912     ewk_view_stop(ewkView);
2913     if (!smartData->api->window_close)
2914         return;
2915     smartData->api->window_close(smartData);
2916 }
2917
2918 /**
2919  * @internal
2920  * Reports mouse has moved over a link.
2921  *
2922  * Emits signal: "link,hover,in"
2923  */
2924 void ewk_view_mouse_link_hover_in(Evas_Object* ewkView, void* data)
2925 {
2926     evas_object_smart_callback_call(ewkView, "link,hover,in", data);
2927 }
2928
2929 /**
2930  * @internal
2931  * Reports mouse is not over a link anymore.
2932  *
2933  * Emits signal: "link,hover,out"
2934  */
2935 void ewk_view_mouse_link_hover_out(Evas_Object* ewkView)
2936 {
2937     evas_object_smart_callback_call(ewkView, "link,hover,out", 0);
2938 }
2939
2940 /**
2941  * @internal
2942  * Set toolbar visible.
2943  *
2944  * Emits signal: "toolbars,visible,set" with a pointer to a boolean.
2945  */
2946 void ewk_view_toolbars_visible_set(Evas_Object* ewkView, bool visible)
2947 {
2948     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
2949     evas_object_smart_callback_call(ewkView, "toolbars,visible,set", &visible);
2950 }
2951
2952 /**
2953  * @internal
2954  * Get toolbar visibility.
2955  *
2956  * @param ewkView View.
2957  * @param visible boolean pointer in which to save the result. It defaults
2958  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
2959  * there are no toolbars and therefore they are not visible.
2960  *
2961  * Emits signal: "toolbars,visible,get" with a pointer to a boolean.
2962  */
2963 void ewk_view_toolbars_visible_get(Evas_Object* ewkView, bool* visible)
2964 {
2965     DBG("%s, ewkView=%p", __func__, ewkView);
2966     *visible = false;
2967     evas_object_smart_callback_call(ewkView, "toolbars,visible,get", visible);
2968 }
2969
2970 /**
2971  * @internal
2972  * Set statusbar visible.
2973  *
2974  * @param ewkView View.
2975  * @param visible @c TRUE if statusbar are visible, @c FALSE otherwise.
2976  *
2977  * Emits signal: "statusbar,visible,set" with a pointer to a boolean.
2978  */
2979 void ewk_view_statusbar_visible_set(Evas_Object* ewkView, bool  visible)
2980 {
2981     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
2982     evas_object_smart_callback_call(ewkView, "statusbar,visible,set", &visible);
2983 }
2984
2985 /**
2986  * @internal
2987  * Get statusbar visibility.
2988  *
2989  * @param ewkView View.
2990  * @param visible boolean pointer in which to save the result. It defaults
2991  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
2992  * there is no statusbar and therefore it is not visible.
2993  *
2994  * Emits signal: "statusbar,visible,get" with a pointer to a boolean.
2995  */
2996 void ewk_view_statusbar_visible_get(Evas_Object* ewkView, bool* visible)
2997 {
2998     DBG("%s, ewkView=%p", __func__, ewkView);
2999     *visible = false;
3000     evas_object_smart_callback_call(ewkView, "statusbar,visible,get", visible);
3001 }
3002
3003 /**
3004  * @internal
3005  * Set text of statusbar
3006  *
3007  * @param ewkView View.
3008  * @param text New text to put on statusbar.
3009  *
3010  * Emits signal: "statusbar,text,set" with a string.
3011  */
3012 void ewk_view_statusbar_text_set(Evas_Object* ewkView, const char* text)
3013 {
3014     DBG("ewkView=%p (text=%s)", ewkView, text);
3015     INFO("status bar text set: %s", text);
3016     evas_object_smart_callback_call(ewkView, "statusbar,text,set", (void*)text);
3017 }
3018
3019 /**
3020  * @internal
3021  * Set scrollbars visible.
3022  *
3023  * @param ewkView View.
3024  * @param visible @c TRUE if scrollbars are visible, @c FALSE otherwise.
3025  *
3026  * Emits signal: "scrollbars,visible,set" with a pointer to a boolean.
3027  */
3028 void ewk_view_scrollbars_visible_set(Evas_Object* ewkView, bool visible)
3029 {
3030     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
3031     evas_object_smart_callback_call(ewkView, "scrollbars,visible,set", &visible);
3032 }
3033
3034 /**
3035  * @internal
3036  * Get scrollbars visibility.
3037  *
3038  * @param ewkView View.
3039  * @param visible boolean pointer in which to save the result. It defaults
3040  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3041  * there are no scrollbars and therefore they are not visible.
3042  *
3043  * Emits signal: "scrollbars,visible,get" with a pointer to a boolean.
3044  */
3045 void ewk_view_scrollbars_visible_get(Evas_Object* ewkView, bool* visible)
3046 {
3047     DBG("%s, ewkView=%p", __func__, ewkView);
3048     *visible = false;
3049     evas_object_smart_callback_call(ewkView, "scrollbars,visible,get", visible);
3050 }
3051
3052 /**
3053  * @internal
3054  * Set menubar visible.
3055  *
3056  * @param ewkView View.
3057  * @param visible @c TRUE if menubar is visible, @c FALSE otherwise.
3058  *
3059  * Emits signal: "menubar,visible,set" with a pointer to a boolean.
3060  */
3061 void ewk_view_menubar_visible_set(Evas_Object* ewkView, bool visible)
3062 {
3063     DBG("ewkView=%p (visible=%d)", ewkView, !!visible);
3064     evas_object_smart_callback_call(ewkView, "menubar,visible,set", &visible);
3065 }
3066
3067 /**
3068  * @internal
3069  * Get menubar visibility.
3070  *
3071  * @param ewkView View.
3072  * @param visible boolean pointer in which to save the result. It defaults
3073  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3074  * there is no menubar and therefore it is not visible.
3075  *
3076  * Emits signal: "menubar,visible,get" with a pointer to a boolean.
3077  */
3078 void ewk_view_menubar_visible_get(Evas_Object* ewkView, bool* visible)
3079 {
3080     DBG("%s, ewkView=%p", __func__, ewkView);
3081     *visible = false;
3082     evas_object_smart_callback_call(ewkView, "menubar,visible,get", visible);
3083 }
3084
3085 /**
3086  * @internal
3087  */
3088 void ewk_view_tooltip_text_set(Evas_Object* ewkView, const char* text)
3089 {
3090     DBG("ewkView=%p text=%s", ewkView, text);
3091     if (text && *text)
3092         evas_object_smart_callback_call(ewkView, "tooltip,text,set", (void*)text);
3093     else
3094         evas_object_smart_callback_call(ewkView, "tooltip,text,unset", 0);
3095 }
3096
3097 /**
3098  * @internal
3099  *
3100  * @param ewkView View.
3101  * @param message String to show on console.
3102  * @param lineNumber Line number.
3103  * @sourceID Source id.
3104  *
3105  */
3106 void ewk_view_add_console_message(Evas_Object* ewkView, const char* message, unsigned int lineNumber, const char* sourceID)
3107 {
3108     DBG("ewkView=%p message=%s lineNumber=%u sourceID=%s", ewkView, message, lineNumber, sourceID);
3109     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3110     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
3111     EINA_SAFETY_ON_NULL_RETURN(smartData->api->add_console_message);
3112     smartData->api->add_console_message(smartData, message, lineNumber, sourceID);
3113 }
3114
3115 bool ewk_view_focus_can_cycle(Evas_Object* ewkView, Ewk_Focus_Direction direction)
3116 {
3117     DBG("ewkView=%p direction=%d", ewkView, direction);
3118     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3119     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3120
3121     if (!smartData->api->focus_can_cycle)
3122         return false;
3123
3124     return smartData->api->focus_can_cycle(smartData, direction);
3125 }
3126
3127 void ewk_view_run_javascript_alert(Evas_Object* ewkView, Evas_Object* frame, const char* message)
3128 {
3129     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3130     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3131     EINA_SAFETY_ON_NULL_RETURN(smartData->api);
3132
3133     if (!smartData->api->run_javascript_alert)
3134         return;
3135
3136     smartData->api->run_javascript_alert(smartData, frame, message);
3137 }
3138
3139 bool ewk_view_run_javascript_confirm(Evas_Object* ewkView, Evas_Object* frame, const char* message)
3140 {
3141     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3142     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3143     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3144
3145     if (!smartData->api->run_javascript_confirm)
3146         return false;
3147
3148     return smartData->api->run_javascript_confirm(smartData, frame, message);
3149 }
3150
3151 bool ewk_view_run_before_unload_confirm(Evas_Object* ewkView, Evas_Object* frame, const char* message)
3152 {
3153     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3154     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3155     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3156
3157     if (!smartData->api->run_before_unload_confirm)
3158         return false;
3159
3160     return smartData->api->run_before_unload_confirm(smartData, frame, message);
3161 }
3162
3163 bool ewk_view_run_javascript_prompt(Evas_Object* ewkView, Evas_Object* frame, const char* message, const char* defaultValue, const char** value)
3164 {
3165     DBG("ewkView=%p frame=%p message=%s", ewkView, frame, message);
3166     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3167     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3168
3169     if (!smartData->api->run_javascript_prompt)
3170         return false;
3171
3172     return smartData->api->run_javascript_prompt(smartData, frame, message, defaultValue, value);
3173 }
3174
3175 /**
3176  * @internal
3177  * Delegates to client to decide whether a script must be stopped because it's
3178  * running for too long. If client does not implement it, it goes to default
3179  * implementation, which logs and returns false. Client may remove log by
3180  * setting this function 0, which will just return false.
3181  *
3182  * @param ewkView View.
3183  *
3184  * @return @c true if script should be stopped; @c false otherwise
3185  */
3186 bool ewk_view_should_interrupt_javascript(Evas_Object* ewkView)
3187 {
3188     DBG("ewkView=%p", ewkView);
3189     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3190     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3191
3192     if (!smartData->api->should_interrupt_javascript)
3193         return false;
3194
3195     return smartData->api->should_interrupt_javascript(smartData);
3196 }
3197
3198 /**
3199  * @internal
3200  * This is called whenever the application is asking to store data to the cache and the
3201  * quota allocated to that application is exceeded. Browser may use this to increase the
3202  * size of quota before the originating operation fails.
3203  *
3204  * @param ewkView View.
3205  * @param origin Security origin.
3206  * @param defaultOriginQuota Default quota for origin.
3207  * @param totalSpaceNeeded The total space needed in the cache in order to fulfill
3208  * application's requirement.
3209  */
3210 int64_t ewk_view_exceeded_application_cache_quota(Evas_Object* ewkView, Ewk_Security_Origin *origin, int64_t defaultOriginQuota, int64_t totalSpaceNeeded)
3211 {
3212     DBG("ewkView=%p", ewkView);
3213     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3214     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, 0);
3215     if (!smartData->api->exceeded_application_cache_quota)
3216         return 0;
3217
3218     INFO("defaultOriginQuota=%" PRIu64 " totalSpaceNeeded=%" PRIu64, defaultOriginQuota, totalSpaceNeeded);
3219     return smartData->api->exceeded_application_cache_quota(smartData, origin, defaultOriginQuota, totalSpaceNeeded);
3220 }
3221
3222 /**
3223  * @internal
3224  * This is called whenever the web site shown in @param frame is asking to store data
3225  * to the database @param databaseName and the quota allocated to that web site
3226  * is exceeded. Browser may use this to increase the size of quota before the
3227  * originating operationa fails.
3228  *
3229  * @param ewkView View.
3230  * @param frame The frame whose web page exceeded its database quota.
3231  * @param databaseName Database name.
3232  * @param currentSize Current size of this database
3233  * @param expectedSize The expected size of this database in order to fulfill
3234  * site's requirement.
3235  */
3236 uint64_t ewk_view_exceeded_database_quota(Evas_Object* ewkView, Evas_Object* frame, const char* databaseName, uint64_t currentSize, uint64_t expectedSize)
3237 {
3238     DBG("ewkView=%p", ewkView);
3239     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3240     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, 0);
3241     if (!smartData->api->exceeded_database_quota)
3242         return 0;
3243
3244     INFO("currentSize=%" PRIu64 " expectedSize=%" PRIu64, currentSize, expectedSize);
3245     return smartData->api->exceeded_database_quota(smartData, frame, databaseName, currentSize, expectedSize);
3246 }
3247
3248 /**
3249  * @internal
3250  * Open panel to choose a file.
3251  *
3252  * @param ewkView View.
3253  * @param frame Frame in which operation is required.
3254  * @param allowsMultipleFiles @c true when more than one file may be selected, @c false otherwise.
3255  * @param acceptMIMETypes List of accepted mime types. It is passed to child objects as an Eina_List of char pointers that is freed automatically.
3256  * @param selectedFilenames List of files selected.
3257  *
3258  * @return @false if user canceled file selection; @true if confirmed.
3259  */
3260 bool ewk_view_run_open_panel(Evas_Object* ewkView, Evas_Object* frame, Ewk_File_Chooser* fileChooser, Eina_List** selectedFilenames)
3261 {
3262     DBG("ewkView=%p frame=%p allows_multiple_files=%d", ewkView, frame, ewk_file_chooser_allows_multiple_files_get(fileChooser));
3263     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3264     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->api, false);
3265
3266     if (!smartData->api->run_open_panel)
3267         return false;
3268
3269     *selectedFilenames = 0;
3270     bool confirm = smartData->api->run_open_panel(smartData, frame, fileChooser, selectedFilenames);    
3271     if (!confirm && *selectedFilenames)
3272         ERR("Canceled file selection, but selected filenames != 0. Free names before return.");
3273
3274     return confirm;
3275 }
3276
3277 /**
3278  * @internal
3279  *
3280  * Marked the change to call frameRectsChanged.
3281  */
3282 void ewk_view_frame_rect_changed(Evas_Object* ewkView)
3283 {
3284     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3285
3286     smartData->changed.frame_rect = true;
3287     _ewk_view_smart_changed(smartData);
3288 }
3289
3290 WTF::PassRefPtr<WebCore::Widget> ewk_view_plugin_create(Evas_Object* ewkView, Evas_Object* frame, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::URL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually)
3291 {
3292     DBG("ewkView=%p, frame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
3293         ewkView, frame, pluginSize.width(), pluginSize.height(), element,
3294         url.string().utf8().data(), mimeType.utf8().data());
3295
3296     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
3297     smartData->changed.frame_rect = true;
3298     _ewk_view_smart_changed(smartData);
3299
3300     return ewk_frame_plugin_create
3301                (frame, pluginSize, element, url, paramNames, paramValues,
3302                mimeType, loadManually);
3303 }
3304
3305 /**
3306  * @internal
3307  *
3308  * Creates a new popup with options when a select widget was clicked.
3309  *
3310  * @param client PopupMenuClient instance that allows communication with webkit.
3311  * @param selected Selected item.
3312  * @param rect Menu's position.
3313  *
3314  * Emits: "popup,create" with a list of Ewk_Menu containing each item's data
3315  */
3316 void ewk_view_popup_new(Evas_Object* ewkView, WebCore::PopupMenuClient* client, int /*selected*/, const WebCore::IntRect& rect)
3317 {
3318     INFO("ewkView=%p", ewkView);
3319     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3320     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3321
3322     if (priv->popup.menuClient)
3323         ewk_view_popup_destroy(ewkView);
3324
3325     priv->popup.menuClient = client;
3326
3327     // populate items
3328     const int size = client->listSize();
3329     for (int i = 0; i < size; ++i) {
3330         Ewk_Menu_Item* item = new Ewk_Menu_Item;
3331         if (client->itemIsSeparator(i))
3332             item->type = EWK_MENU_SEPARATOR;
3333         else if (client->itemIsLabel(i))
3334             item->type = EWK_MENU_GROUP;
3335         else
3336             item->type = EWK_MENU_OPTION;
3337         item->text = eina_stringshare_add(client->itemText(i).utf8().data());
3338
3339         priv->popup.menu.items = eina_list_append(priv->popup.menu.items, item);
3340     }
3341
3342     priv->popup.menu.x = rect.x();
3343     priv->popup.menu.y = rect.y();
3344     priv->popup.menu.width = rect.width();
3345     priv->popup.menu.height = rect.height();
3346     evas_object_smart_callback_call(ewkView, "popup,create", &priv->popup.menu);
3347 }
3348
3349 Eina_Bool ewk_view_popup_destroy(Evas_Object* ewkView)
3350 {
3351     INFO("ewkView=%p", ewkView);
3352     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3353     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3354
3355     if (!priv->popup.menuClient)
3356         return false;
3357
3358     evas_object_smart_callback_call(ewkView, "popup,willdelete", &priv->popup.menu);
3359
3360     void* itemv;
3361     EINA_LIST_FREE(priv->popup.menu.items, itemv) {
3362         Ewk_Menu_Item* item = static_cast<Ewk_Menu_Item*>(itemv);
3363         eina_stringshare_del(item->text);
3364         delete item;
3365     }
3366     priv->popup.menuClient->popupDidHide();
3367     priv->popup.menuClient = 0;
3368
3369     return true;
3370 }
3371
3372 void ewk_view_popup_selected_set(Evas_Object* ewkView, int index)
3373 {
3374     INFO("ewkView=%p", ewkView);
3375     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3376     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3377     EINA_SAFETY_ON_NULL_RETURN(priv->popup.menuClient);
3378
3379     priv->popup.menuClient->valueChanged(index);
3380 }
3381
3382 #if ENABLE(INPUT_TYPE_COLOR)
3383 /**
3384  * @internal
3385  *
3386  * Creates a new color chooser with an initial selected color.
3387  *
3388  * @param client ColorChooserClient instance that allows communication with webkit.
3389  * @param initialColor The initial selected color.
3390  *
3391  */
3392 void ewk_view_color_chooser_new(Evas_Object* ewkView, WebCore::ColorChooserClient* client, const WebCore::Color& initialColor)
3393 {
3394     INFO("ewkView=%p", ewkView);
3395     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3396     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3397
3398     if (priv->colorChooserClient)
3399         ewk_view_color_chooser_destroy(ewkView);
3400
3401     priv->colorChooserClient = client;
3402
3403     Ewk_Color color;
3404     color.r = initialColor.red();
3405     color.g = initialColor.green();
3406     color.b = initialColor.blue();
3407     color.a = initialColor.alpha();
3408
3409     evas_object_smart_callback_call(ewkView, "colorchooser,create", &color);
3410 }
3411
3412 Eina_Bool ewk_view_color_chooser_destroy(Evas_Object* ewkView)
3413 {
3414     INFO("ewkView=%p", ewkView);
3415     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3416     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3417
3418     if (!priv->colorChooserClient)
3419         return false;
3420
3421     evas_object_smart_callback_call(ewkView, "colorchooser,willdelete", 0);
3422
3423     priv->colorChooserClient->didEndChooser();
3424     priv->colorChooserClient = 0;
3425
3426     return true;
3427 }
3428
3429 void ewk_view_color_chooser_color_set(Evas_Object *ewkView, int r, int g, int b)
3430 {
3431     INFO("ewkView=%p", ewkView);
3432     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3433     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3434     EINA_SAFETY_ON_NULL_RETURN(priv->colorChooserClient);
3435
3436     // Alpha channel is not allowed, see ColorInputType::sanitizeValue().
3437     priv->colorChooserClient->didChooseColor(WebCore::Color(r, g, b));
3438 }
3439
3440 /**
3441  * @internal
3442  *
3443  * The selected color of the color input associated with the color chooser has
3444  * changed. Usually the browser should updated the current selected value on the
3445  * color picker if the user is not interacting.
3446  *
3447  * @param newColor The new selected color.
3448  *
3449  */
3450 void ewk_view_color_chooser_changed(Evas_Object* ewkView, const WebCore::Color& newColor)
3451 {
3452     INFO("ewkView=%p", ewkView);
3453
3454     Ewk_Color color;
3455     color.r = newColor.red();
3456     color.g = newColor.green();
3457     color.b = newColor.blue();
3458     color.a = newColor.alpha();
3459
3460     evas_object_smart_callback_call(ewkView, "colorchooser,color,changed", &color);
3461 }
3462 #endif
3463
3464 /**
3465  * @internal
3466  * Request a download to user.
3467  *
3468  * @param ewkView View.
3469  * @oaram download Ewk_Download struct to be sent.
3470  *
3471  * Emits: "download,request" with an Ewk_Download containing the details of the
3472  * requested download. The download per se must be handled outside of webkit.
3473  */
3474 void ewk_view_download_request(Evas_Object* ewkView, Ewk_Download* download)
3475 {
3476     DBG("ewkView=%p", ewkView);
3477     evas_object_smart_callback_call(ewkView, "download,request", download);
3478 }
3479
3480 #if ENABLE(NETSCAPE_PLUGIN_API)
3481 /**
3482  * @internal
3483  * Reports the JS window object was cleared.
3484  *
3485  * @param ewkView view.
3486  * @param frame the frame.
3487  */
3488 void ewk_view_js_window_object_clear(Evas_Object* ewkView, Evas_Object* frame)
3489 {
3490     evas_object_smart_callback_call(ewkView, "js,windowobject,clear", frame);
3491 }
3492 #endif
3493
3494 /**
3495  * @internal
3496  * Reports the viewport has changed.
3497  *
3498  * @param arguments viewport argument.
3499  *
3500  * Emits signal: "viewport,changed" with no parameters.
3501  */
3502 void ewk_view_viewport_attributes_set(Evas_Object* ewkView, const WebCore::ViewportArguments& arguments)
3503 {
3504     EWK_VIEW_SD_GET(ewkView, smartData);
3505     EWK_VIEW_PRIV_GET(smartData, priv);
3506
3507     priv->viewportArguments = arguments;
3508     evas_object_smart_callback_call(ewkView, "viewport,changed", 0);
3509 }
3510
3511 void ewk_view_viewport_attributes_get(const Evas_Object* ewkView, int* width, int* height, float* initScale, float* maxScale, float* minScale, float* devicePixelRatio, Eina_Bool* userScalable)
3512 {
3513     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3514     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3515     WebCore::ViewportAttributes attributes = _ewk_view_viewport_attributes_compute(priv);
3516
3517     if (width)
3518         *width = attributes.layoutSize.width();
3519     if (height)
3520         *height = attributes.layoutSize.height();
3521     if (initScale)
3522         *initScale = attributes.initialScale;
3523     if (maxScale)
3524         *maxScale = attributes.maximumScale;
3525     if (minScale)
3526         *minScale = attributes.minimumScale;
3527     if (devicePixelRatio)
3528         *devicePixelRatio = priv->page->deviceScaleFactor();
3529     if (userScalable)
3530         *userScalable = static_cast<bool>(attributes.userScalable);
3531 }
3532
3533 Eina_Bool ewk_view_zoom_range_set(Evas_Object* ewkView, float minScale, float maxScale)
3534 {
3535     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3536     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3537
3538     if (maxScale < minScale) {
3539         WARN("minScale is larger than maxScale");
3540         return false;
3541     }
3542
3543     priv->settings.zoomRange.minScale = minScale;
3544     priv->settings.zoomRange.maxScale = maxScale;
3545
3546     return true;
3547 }
3548
3549 float ewk_view_zoom_range_min_get(const Evas_Object* ewkView)
3550 {
3551     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3552     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3553
3554     return priv->settings.zoomRange.minScale;
3555 }
3556
3557 float ewk_view_zoom_range_max_get(const Evas_Object* ewkView)
3558 {
3559     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3560     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3561
3562     return priv->settings.zoomRange.maxScale;
3563 }
3564
3565 Eina_Bool ewk_view_user_scalable_set(Evas_Object* ewkView, Eina_Bool userScalable)
3566 {
3567     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3568     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3569
3570     priv->settings.zoomRange.userScalable = userScalable;
3571
3572     return true;
3573 }
3574
3575 Eina_Bool ewk_view_user_scalable_get(const Evas_Object* ewkView)
3576 {
3577     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3578     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3579
3580     return priv->settings.zoomRange.userScalable;
3581 }
3582
3583 Eina_Bool ewk_view_device_pixel_ratio_set(Evas_Object* ewkView, float ratio)
3584 {
3585     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, false);
3586     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false);
3587
3588     priv->page->setDeviceScaleFactor(ratio);
3589
3590     return true;
3591 }
3592
3593 float ewk_view_device_pixel_ratio_get(const Evas_Object* ewkView)
3594 {
3595     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, -1.0);
3596     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, -1.0);
3597
3598     return priv->page->deviceScaleFactor();
3599 }
3600
3601 void ewk_view_text_direction_set(Evas_Object* ewkView, Ewk_Text_Direction direction)
3602 {
3603     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3604     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3605
3606     // The Editor::setBaseWritingDirection() function checks if we can change
3607     // the text direction of the selected node and updates its DOM "dir"
3608     // attribute and its CSS "direction" property.
3609     // So, we just call the function as Safari does.
3610     WebCore::Frame& focusedFrame = priv->page->focusController().focusedOrMainFrame();
3611
3612     WebCore::Editor& editor = focusedFrame.editor();
3613     if (!editor.canEdit())
3614         return;
3615
3616     switch (direction) {
3617     case EWK_TEXT_DIRECTION_DEFAULT:
3618         editor.setBaseWritingDirection(NaturalWritingDirection);
3619     case EWK_TEXT_DIRECTION_LEFT_TO_RIGHT:
3620         editor.setBaseWritingDirection(LeftToRightWritingDirection);
3621     case EWK_TEXT_DIRECTION_RIGHT_TO_LEFT:
3622         editor.setBaseWritingDirection(RightToLeftWritingDirection);
3623     }
3624
3625     ASSERT_NOT_REACHED();
3626 }
3627
3628 void ewk_view_transition_to_commited_for_newpage(Evas_Object* ewkView)
3629 {
3630     EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
3631     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
3632
3633     ewk_view_disable_render(ewkView);
3634     priv->flags.viewCleared = false;
3635 }
3636
3637
3638 /**
3639  * @internal
3640  * Reports that a navigation policy decision should be taken. If @return
3641  * is true, the navigation request will be accepted, otherwise it will be
3642  * ignored.
3643  *
3644  * @param ewkView View to load
3645  * @param request Request which contain url to n