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