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