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