tizen beta release
[framework/web/webkit-efl.git] / Source / WebKit / efl / ewk / ewk_frame.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2010 Samsung Electronics
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 // Uncomment to view frame regions and debug messages
22 // #define EWK_FRAME_DEBUG
23
24 #include "config.h"
25 #include "ewk_frame.h"
26
27 #include "DocumentMarkerController.h"
28 #include "EWebKit.h"
29 #include "EventHandler.h"
30 #include "FocusController.h"
31 #include "FrameLoaderClientEfl.h"
32 #include "FrameView.h"
33 #include "HTMLCollection.h"
34 #include "HTMLHeadElement.h"
35 #include "HTMLImageElement.h"
36 #include "HTMLNames.h"
37 #include "HTMLPlugInElement.h"
38 #include "HistoryItem.h"
39 #include "HitTestResult.h"
40 #include "IntSize.h"
41 #include "KURL.h"
42 #include "PlatformKeyboardEvent.h"
43 #include "PlatformMouseEvent.h"
44 #include "PlatformTouchEvent.h"
45 #include "PlatformWheelEvent.h"
46 #include "ProgressTracker.h"
47 #include "RefPtr.h"
48 #include "RenderText.h"
49 #include "RenderTheme.h"
50 #include "ResourceRequest.h"
51 #include "ScriptValue.h"
52 #include "SharedBuffer.h"
53 #include "SubstituteData.h"
54 #include "WindowsKeyboardCodes.h"
55 #include "ewk_private.h"
56
57 #include <Eina.h>
58 #include <Evas.h>
59 #include <algorithm>
60 #include <eina_safety_checks.h>
61 #include <wtf/text/CString.h>
62
63 #if ENABLE(TIZEN_GEOLOCATION)
64 #include "Geolocation.h"
65 #include "Navigator.h"
66 #endif
67
68 #if ENABLE(TIZEN_TEXT_SELECTION)
69 #include "FrameSelection.h"
70 #include "RenderView.h"
71 #include "VisibleSelection.h"
72 #include "htmlediting.h" // for comparePositions()
73 #endif
74
75 #if ENABLE(TIZEN_PARAGRAPH_SELECTION)
76 #include "WebCore/editing/visible_units.h"
77 #endif
78
79 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
80 #include "NodeList.h"
81 #endif
82
83 #if ENABLE(TIZEN_SMART_FOCUSING)
84 #include "SmartFocus.h"
85 #endif
86
87 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
88 #include "ExceptionCode.h"
89 #include "Storage.h"
90 #endif
91
92 #if ENABLE(TIZEN_ISF_PORT)
93 #include "EditorClientEfl.h"
94 #endif
95
96 #if ENABLE(TIZEN_EVAS_OBJECT_PLUGIN)
97 #include "RenderEmbeddedObject.h"
98 #include "RenderLayer.h"
99 #endif
100 #if ENABLE(TIZEN_EWK_ERROR_PAGE)
101 #include "ewk_errorpage.h"
102 #endif
103
104 #if ENABLE(TIZEN_ONSCROLL_EVENT_SUPPRESSION)
105 #include "EventQueue.h"
106 #endif
107
108 #if ENABLE(TIZEN_WEBKIT_EFL_DRT)
109 #include "DocumentLoader.h"
110 #include "PrintContext.h"
111 #include "RenderTreeAsText.h"
112 #include "SVGDocumentExtensions.h"
113 #include "SVGSMILElement.h"
114 #endif
115
116
117 static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame";
118
119 struct Ewk_Frame_Smart_Data {
120     Evas_Object_Smart_Clipped_Data base;
121     Evas_Object* self;
122     Evas_Object* view;
123 #ifdef EWK_FRAME_DEBUG
124     Evas_Object* region;
125 #endif
126     WebCore::Frame* frame;
127     const char* title;
128     const char* uri;
129     const char* name;
130     Eina_Bool textZoom:1;
131     Eina_Bool editable : 1;
132 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
133     Eina_Bool cairoScaling : 1;
134 #endif
135 #if ENABLE(TIZEN_WEAK_SCROLL)
136     struct {
137         Eina_Bool enabled : 1;
138         int dx, dy;
139         Eina_Bool movingViewport : 1;
140     } weakScroll;
141 #endif
142 };
143
144 struct Eina_Iterator_Ewk_Frame {
145     Eina_Iterator base;
146     Evas_Object* object;
147     unsigned currentIndex;
148 };
149 #if ENABLE(TIZEN_EWK_ERROR_PAGE)
150 #define MAX_LOAD_ERROR_BUFFER_SIZE 3500
151 #define MAX_LOAD_ERROR_TYPE_SIZE 64
152 #define MAX_LOAD_ERROR_CAUSE_SIZE 256
153 #endif
154
155 #if ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
156
157 #ifndef EWK_TYPE_CHECK
158 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
159 #else
160 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...)                                    \
161     do {                                                                \
162         const char *_tmp_otype = evas_object_type_get(ewkFrame);               \
163         if (EINA_UNLIKELY(!_tmp_otype)) {                               \
164             EINA_LOG_CRIT("%p (null) is not of an ewk_frame!", ewkFrame);      \
165             return __VA_ARGS__;                                         \
166         }                                                               \
167         if (EINA_UNLIKELY(strncmp(_tmp_otype, EWK_FRAME_TYPE_STR, strlen(EWK_FRAME_TYPE_STR))))  {          \
168             EINA_LOG_CRIT                                               \
169                 ("%p (%s) is not of an ewk_frame!", ewkFrame,                  \
170                  _tmp_otype ? _tmp_otype : "(null)");                   \
171             return __VA_ARGS__;                                         \
172         }                                                               \
173     } while (0)
174 #endif
175
176 #else //ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
177
178 #ifndef EWK_TYPE_CHECK
179 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
180 #else
181 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...)                                    \
182     do {                                                                \
183         const char* _tmp_otype = evas_object_type_get(ewkFrame);               \
184         if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) {          \
185             EINA_LOG_CRIT                                               \
186                 ("%p (%s) is not of an ewk_frame!", ewkFrame,                  \
187                 _tmp_otype ? _tmp_otype : "(null)");                    \
188             return __VA_ARGS__;                                         \
189         }                                                               \
190     } while (0)
191 #endif
192
193 #endif //ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
194
195 #define EWK_FRAME_SD_GET(ewkFrame, ptr)                                \
196     Ewk_Frame_Smart_Data* ptr = static_cast<Ewk_Frame_Smart_Data*>(evas_object_smart_data_get(ewkFrame))
197
198 #define EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, ptr, ...)         \
199     EWK_FRAME_TYPE_CHECK(ewkFrame, __VA_ARGS__);               \
200     EWK_FRAME_SD_GET(ewkFrame, ptr);                           \
201     if (!ptr) {                                         \
202         CRITICAL("no smart data for object %p (%s)",    \
203                  ewkFrame, evas_object_type_get(ewkFrame));           \
204         return __VA_ARGS__;                             \
205     }
206
207 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
208
209 #ifdef EWK_FRAME_DEBUG
210 static inline void _ewk_frame_debug(Evas_Object* ewkFrame)
211 {
212     Evas_Object* clip, * parent;
213     Evas_Coord x, y, width, height, contentX, contentY, contentWidth, contentHeight;
214     int red, green, blue, alpha, contentRed, contentGreen, contentBlue, contentAlpha;
215
216     evas_object_color_get(ewkFrame, &red, &green, &blue, &alpha);
217     evas_object_geometry_get(ewkFrame, &x, &y, &width, &height);
218
219     clip = evas_object_clip_get(ewkFrame);
220     evas_object_color_get(clip, &contentRed, &contentGreen, &contentBlue, &contentAlpha);
221     evas_object_geometry_get(clip, &contentX, &contentY, &contentWidth, &contentHeight);
222
223     fprintf(stderr, "%p: type=%s name=%s, visible=%d, color=%02x%02x%02x%02x, %d,%d+%dx%d, clipper=%p (%d, %02x%02x%02x%02x, %d,%d+%dx%d)\n",
224             ewkFrame, evas_object_type_get(ewkFrame), evas_object_name_get(ewkFrame), evas_object_visible_get(ewkFrame),
225             red, green, blue, alpha, x, y, width, height,
226             clip, evas_object_visible_get(clip), contentRed, contentGreen, contentBlue, contentAlpha, contentX, contentY, contentWidth, contentHeight);
227     parent = evas_object_smart_parent_get(ewkFrame);
228     if (!parent)
229         fprintf(stderr, "\n");
230     else
231         _ewk_frame_debug(parent);
232 }
233 #endif
234
235 static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(const WebCore::Frame* frame)
236 {
237     return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client());
238 }
239
240 static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* iterator, Evas_Object** data)
241 {
242     EWK_FRAME_SD_GET_OR_RETURN(iterator->object, smartData, false);
243     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
244
245     WebCore::FrameTree* tree = smartData->frame->tree(); // check if it's still valid
246     EINA_SAFETY_ON_NULL_RETURN_VAL(tree, false);
247
248     if (iterator->currentIndex < tree->childCount()) {
249         *data = EWKPrivate::kitFrame(tree->child(iterator->currentIndex++));
250         return true;
251     }
252
253     return false;
254 }
255
256 static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* iterator)
257 {
258     return iterator->object;
259 }
260
261 static void _ewk_frame_smart_add(Evas_Object* ewkFrame)
262 {
263     EWK_FRAME_SD_GET(ewkFrame, smartData);
264
265     if (!smartData) {
266         smartData = static_cast<Ewk_Frame_Smart_Data*>(calloc(1, sizeof(Ewk_Frame_Smart_Data)));
267         if (!smartData) {
268             CRITICAL("could not allocate Ewk_Frame_Smart_Data");
269             return;
270         }
271         evas_object_smart_data_set(ewkFrame, smartData);
272     }
273
274     smartData->self = ewkFrame;
275
276     _parent_sc.add(ewkFrame);
277     evas_object_static_clip_set(smartData->base.clipper, false);
278     evas_object_move(smartData->base.clipper, 0, 0);
279     evas_object_resize(smartData->base.clipper, 0, 0);
280
281 #ifdef EWK_FRAME_DEBUG
282     smartData->region = evas_object_rectangle_add(smartData->base.evas);
283     static int i = 0;
284     switch (i) {
285     case 0:
286         evas_object_color_set(smartData->region, 128, 0, 0, 128);
287         break;
288     case 1:
289         evas_object_color_set(smartData->region, 0, 128, 0, 128);
290         break;
291     case 2:
292         evas_object_color_set(smartData->region, 0, 0, 128, 128);
293         break;
294     case 3:
295         evas_object_color_set(smartData->region, 128, 0, 0, 128);
296         break;
297     case 4:
298         evas_object_color_set(smartData->region, 128, 128, 0, 128);
299         break;
300     case 5:
301         evas_object_color_set(smartData->region, 128, 0, 128, 128);
302         break;
303     case 6:
304         evas_object_color_set(smartData->region, 0, 128, 128, 128);
305         break;
306     default:
307         break;
308     }
309     i++;
310     if (i > 6)
311         i = 0;
312
313     evas_object_smart_member_add(smartData->region, ewkFrame);
314     evas_object_hide(smartData->region);
315 #endif
316 #if ENABLE(TIZEN_WEAK_SCROLL)
317     smartData->weakScroll.dx = 0;
318     smartData->weakScroll.dy = 0;
319     smartData->weakScroll.enabled = false;
320     smartData->weakScroll.movingViewport = true;
321 #endif
322
323 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH) //check
324     smartData->cairoScaling = true;
325 #endif
326 }
327
328 static void _ewk_frame_smart_del(Evas_Object* ewkFrame)
329 {
330     EWK_FRAME_SD_GET(ewkFrame, smartData);
331
332     if (smartData) {
333         if (smartData->frame) {
334             WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(smartData->frame);
335             flc->setWebFrame(0);
336             smartData->frame->loader()->detachFromParent();
337             smartData->frame->loader()->cancelAndClear();
338             smartData->frame = 0;
339         }
340
341         eina_stringshare_del(smartData->title);
342         eina_stringshare_del(smartData->uri);
343         eina_stringshare_del(smartData->name);
344     }
345
346     _parent_sc.del(ewkFrame);
347 }
348
349 static void _ewk_frame_smart_resize(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
350 {
351     EWK_FRAME_SD_GET(ewkFrame, smartData);
352     evas_object_resize(smartData->base.clipper, width, height);
353
354 #ifdef EWK_FRAME_DEBUG
355     evas_object_resize(smartData->region, width, height);
356     Evas_Coord x, y;
357     evas_object_geometry_get(smartData->region, &x, &y, &width, &height);
358     INF("region=%p, visible=%d, geo=%d,%d + %dx%d",
359         smartData->region, evas_object_visible_get(smartData->region), x, y, width, height);
360     _ewk_frame_debug(ewkFrame);
361 #endif
362 }
363
364 static void _ewk_frame_smart_set(Evas_Smart_Class* api)
365 {
366     evas_object_smart_clipped_smart_set(api);
367     api->add = _ewk_frame_smart_add;
368     api->del = _ewk_frame_smart_del;
369     api->resize = _ewk_frame_smart_resize;
370 }
371
372 static inline Evas_Smart* _ewk_frame_smart_class_new(void)
373 {
374 #if ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
375     static Evas_Smart_Class smartClass = EVAS_SMART_CLASS_INIT_VERSION;
376     const char *name = eina_stringshare_add("EWK_Frame");
377     smartClass.name = name;
378 #else
379     static Evas_Smart_Class smartClass = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR);
380 #endif
381     static Evas_Smart* smart = 0;
382
383     if (EINA_UNLIKELY(!smart)) {
384         evas_object_smart_clipped_smart_set(&_parent_sc);
385         _ewk_frame_smart_set(&smartClass);
386         smart = evas_smart_class_new(&smartClass);
387     }
388
389     return smart;
390 }
391
392 Evas_Object* ewk_frame_view_get(const Evas_Object* ewkFrame)
393 {
394     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
395     return smartData->view;
396 }
397
398 Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* ewkFrame)
399 {
400     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
401     Eina_Iterator_Ewk_Frame* iterator = static_cast<Eina_Iterator_Ewk_Frame*>
402                                   (calloc(1, sizeof(Eina_Iterator_Ewk_Frame)));
403     if (!iterator)
404         return 0;
405
406     EINA_MAGIC_SET(&iterator->base, EINA_MAGIC_ITERATOR);
407     iterator->base.next = FUNC_ITERATOR_NEXT(_ewk_frame_children_iterator_next);
408     iterator->base.get_container = FUNC_ITERATOR_GET_CONTAINER(_ewk_frame_children_iterator_get_container);
409     iterator->base.free = FUNC_ITERATOR_FREE(free);
410     iterator->object = ewkFrame;
411     iterator->currentIndex = 0;
412     return &iterator->base;
413 }
414
415 Evas_Object* ewk_frame_child_find(Evas_Object* ewkFrame, const char* name)
416 {
417     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
418     EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
419     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
420     WTF::String frameName = WTF::String::fromUTF8(name);
421     return EWKPrivate::kitFrame(smartData->frame->tree()->find(WTF::AtomicString(frameName)));
422 }
423
424 Eina_Bool ewk_frame_uri_set(Evas_Object* ewkFrame, const char* uri)
425 {
426     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
427 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
428     eina_stringshare_replace(&smartData->uri, uri);
429 #endif
430     WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri));
431     WebCore::ResourceRequest req(kurl);
432     WebCore::FrameLoader* loader = smartData->frame->loader();
433     loader->load(req, false);
434     return true;
435 }
436
437 const char* ewk_frame_uri_get(const Evas_Object* ewkFrame)
438 {
439     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
440     return smartData->uri;
441 }
442
443 const char* ewk_frame_title_get(const Evas_Object* ewkFrame)
444 {
445     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
446     return smartData->title;
447 }
448
449 const char* ewk_frame_name_get(const Evas_Object* ewkFrame)
450 {
451     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
452
453     if (!smartData->frame) {
454         ERR("could not get name of uninitialized frame.");
455         return 0;
456     }
457
458     const WTF::String frameName = smartData->frame->tree()->uniqueName();
459
460     if ((smartData->name) && (smartData->name == frameName))
461         return smartData->name;
462
463     eina_stringshare_replace_length(&(smartData->name), frameName.utf8().data(), frameName.length());
464
465     return smartData->name;
466 }
467
468 Eina_Bool ewk_frame_contents_size_get(const Evas_Object* ewkFrame, Evas_Coord* width, Evas_Coord* height)
469 {
470     if (width)
471         *width = 0;
472     if (height)
473         *height = 0;
474     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
475     if (!smartData->frame || !smartData->frame->view())
476         return false;
477     if (width)
478         *width = smartData->frame->view()->contentsWidth();
479     if (height)
480         *height = smartData->frame->view()->contentsHeight();
481     return true;
482 }
483
484 static Eina_Bool _ewk_frame_contents_set_internal(Ewk_Frame_Smart_Data* smartData, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri, const char* unreachableUri)
485 {
486     size_t length = strlen(contents);
487     if (contentsSize < 1 || contentsSize > length)
488         contentsSize = length;
489     if (!mimeType)
490         mimeType = "text/html";
491     if (!encoding)
492         encoding = "UTF-8";
493     if (!baseUri)
494         baseUri = "about:blank";
495
496     WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(baseUri));
497     WebCore::KURL unreachableKURL;
498     if (unreachableUri)
499         unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachableUri));
500     else
501         unreachableKURL = WebCore::KURL();
502
503     WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contentsSize);
504     WebCore::SubstituteData substituteData
505         (buffer.release(),
506         WTF::String::fromUTF8(mimeType),
507         WTF::String::fromUTF8(encoding),
508         baseKURL, unreachableKURL);
509     WebCore::ResourceRequest request(baseKURL);
510
511     smartData->frame->loader()->load(request, substituteData, false);
512     return true;
513 }
514
515 Eina_Bool ewk_frame_contents_set(Evas_Object* ewkFrame, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri)
516 {
517     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
518     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
519     EINA_SAFETY_ON_NULL_RETURN_VAL(contents, false);
520     return _ewk_frame_contents_set_internal
521                (smartData, contents, contentsSize, mimeType, encoding, baseUri, 0);
522 }
523
524 Eina_Bool ewk_frame_contents_alternate_set(Evas_Object* ewkFrame, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri, const char* unreachableUri)
525 {
526     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
527     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
528     EINA_SAFETY_ON_NULL_RETURN_VAL(contents, false);
529     EINA_SAFETY_ON_NULL_RETURN_VAL(unreachableUri, false);
530     return _ewk_frame_contents_set_internal
531                (smartData, contents, contentsSize, mimeType, encoding, baseUri,
532                unreachableUri);
533 }
534
535 char* ewk_frame_script_execute(Evas_Object* ewkFrame, const char* script)
536 {
537     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
538     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
539     EINA_SAFETY_ON_NULL_RETURN_VAL(script, 0);
540
541     WTF::String resultString;
542     JSC::JSValue result = smartData->frame->script()->executeScript(WTF::String::fromUTF8(script), true).jsValue();
543
544     if (!smartData->frame) // In case the script removed our frame from the page.
545         return 0;
546
547 #if ENABLE(TIZEN_RETURN_OBJECT_RESULT_FROM_EXECUTE_SCRIPT)
548     if (!result)
549 #else
550     if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
551 #endif
552         return 0;
553
554     JSC::JSLock lock(JSC::SilenceAssertionsOnly);
555     resultString = WebCore::ustringToString(result.toString(smartData->frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec()));
556     return strdup(resultString.utf8().data());
557 }
558
559 Eina_Bool ewk_frame_editable_get(const Evas_Object* ewkFrame)
560 {
561     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
562     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
563     return smartData->editable;
564 }
565
566 Eina_Bool ewk_frame_editable_set(Evas_Object* ewkFrame, Eina_Bool editable)
567 {
568     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
569     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
570     editable = !!editable;
571     if (smartData->editable == editable)
572         return true;
573     if (editable)
574         smartData->frame->editor()->applyEditingStyleToBodyElement();
575     return true;
576 }
577
578 char* ewk_frame_selection_get(const Evas_Object* ewkFrame)
579 {
580     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
581     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
582     WTF::CString s = smartData->frame->editor()->selectedText().utf8();
583     if (s.isNull())
584         return 0;
585     return strdup(s.data());
586 }
587
588 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
589 static inline Eina_Bool _ewk_frame_editor_command(Ewk_Frame_Smart_Data* smartData, const char* command)
590 {
591     return smartData->frame->editor()->command(WTF::String::fromUTF8(command)).execute();
592 }
593 #endif
594
595 /**
596  * Unselects whatever was selected.
597  *
598  * @return @c true if operation was executed, @c false otherwise.
599  */
600 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
601 Eina_Bool ewk_frame_select_none(const Evas_Object* ewkFrame)
602 {
603     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
604     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
605     return _ewk_frame_editor_command(smartData, "Unselect");
606 }
607 #endif
608
609 /**
610  * Selects everything.
611  *
612  * @return @c true if operation was executed, @c false otherwise.
613  */
614 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
615 Eina_Bool ewk_frame_select_all(const Evas_Object* ewkFrame)
616 {
617     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
618     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
619     return _ewk_frame_editor_command(smartData, "SelectAll");
620 }
621 #endif
622
623 /**
624  * Get the copy of the selection text.
625  *
626  * @param ewkFrame frame object to get selection text.
627  * @param x1 leftmost coordinate of selection rectangle.
628  * @param y1 upper coordinate of selection rectangle.
629  * @param x2 rightmost coordinate of selection rectangle.
630  * @param y2 bottom coordinate of selection rectangle.
631  *
632  * @return newly allocated string or @c NULL if nothing is selected or failure.
633  */
634
635 char* ewk_frame_select_text(const Evas_Object*ewkFrame, int x1, int y1, int x2, int y2)
636 {
637 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
638     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
639     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
640
641     WebCore::FrameSelection* fs = smartData->frame->selection();
642
643     int centerX = (x2 + x1) / 2;
644     int centerY = (y2 + y1) / 2;
645
646     WebCore::IntPoint tmpPoint = smartData->frame->view()->contentsToWindow(WebCore::IntPoint(centerX, centerY));
647     centerX = tmpPoint.x();
648     centerY = tmpPoint.y();
649
650     unsigned topPadding = (y2 - y1) / 2;
651     unsigned rightPadding = (x2 - x1) / 2;
652     unsigned bottomPadding = topPadding;
653     unsigned leftPadding = rightPadding;
654
655     WTF::PassRefPtr<WebCore::NodeList> nodes = smartData->frame->document()->nodesFromRect(centerX , centerY , topPadding, rightPadding, bottomPadding, leftPadding, true);
656
657     WebCore::IntRect selectionRectangle(x1, y1, x2 - x1, y2 - y1);
658
659     WebCore::Node* firstTextNode = 0;
660     WebCore::Node* lastTextNode = 0;
661     // find the last text node amongst all nodes from rect
662     for (unsigned i = 0; nodes && i < nodes->length(); ++i) {
663         if (nodes->item(i)->nodeType() == WebCore::Node::TEXT_NODE) {
664             if (!lastTextNode) {
665                 WebCore::Node* tmpNode = nodes->item(i);
666
667                 if (selectionRectangle.intersects(tmpNode->getRect())) {
668                     lastTextNode = nodes->item(i);
669                     break;
670                 }
671             }
672         }
673     }
674     if (!lastTextNode)
675         return 0;
676
677     // find the first text node amongst all nodes from rect
678     for (int i = nodes->length() - 1; nodes && i >= 0; --i) {
679         if (nodes->item(i)->nodeType() == WebCore::Node::TEXT_NODE) {
680             if (!firstTextNode) {
681                 WebCore::Node* tmpNode = nodes->item(i);
682
683                 if (selectionRectangle.intersects(tmpNode->getRect())) {
684                     firstTextNode = nodes->item(i);
685                     break;
686                 }
687             }
688         }
689     }
690     if (!firstTextNode)
691         return 0;
692
693     // find visable position for [top, left] vertex inside first text node
694     WebCore::IntPoint p1(x1, y1);
695
696     WebCore::RenderText* firstNodeRender = (WebCore::RenderText*)firstTextNode->renderer();
697     if (!firstNodeRender)
698         EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
699
700     WebCore::VisiblePosition position1(firstNodeRender->positionForAbsolutePoint(p1, true));
701
702     // find visable position for [bottom, right] vertex inside last text node
703     WebCore::IntPoint p2(x2, y2);
704
705     WebCore::RenderText* lastNodeRender = (WebCore::RenderText*)lastTextNode->renderer();
706     if (!lastNodeRender)
707         EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
708
709     WebCore::VisiblePosition position2(lastNodeRender->positionForAbsolutePoint(p2, false));
710
711     // select all and then move selection boundaries to proper positions
712     ewk_frame_select_all(ewkFrame);
713
714     fs->setBase(position2, WebCore::NotUserTriggered);
715     fs->setExtent(position1, WebCore::NotUserTriggered);
716
717     char* text = ewk_frame_selection_get(ewkFrame);
718
719     ewk_frame_select_none(ewkFrame);
720
721     return text;
722 #else
723     LOG_ERROR("TIZEN_SELECT_TEXT_FROM_RECTANGLE macro is disabled.\n");
724     return 0;
725
726 #endif
727 }
728
729 Eina_Bool ewk_frame_text_search(const Evas_Object* ewkFrame, const char* text, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
730 {
731     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
732     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
733     EINA_SAFETY_ON_NULL_RETURN_VAL(text, false);
734
735     return smartData->frame->editor()->findString(WTF::String::fromUTF8(text), forward, caseSensitive, wrap, true);
736 }
737
738 unsigned int ewk_frame_text_matches_mark(Evas_Object* ewkFrame, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
739 {
740     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
741     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
742     EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
743
744     smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
745     return smartData->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), caseSensitive, limit, true);
746 }
747
748 Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* ewkFrame)
749 {
750     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
751     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
752
753     smartData->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch);
754     return true;
755 }
756
757 Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* ewkFrame, Eina_Bool highlight)
758 {
759     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
760     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
761     smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
762     return true;
763 }
764
765 Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* ewkFrame)
766 {
767     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
768     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
769     return smartData->frame->editor()->markedTextMatchesAreHighlighted();
770 }
771
772 /**
773  * Comparison function used by ewk_frame_text_matches_nth_pos_get
774  */
775 static Eina_Bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& begin, const WebCore::IntRect& end)
776 {
777     return (begin.y() < end.y() || (begin.y() == end.y() && begin.x() < end.x()));
778 }
779
780 /**
781  * Predicate used by ewk_frame_text_matches_nth_pos_get
782  */
783 static Eina_Bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& rect)
784 {
785     return (rect.x() < 0 || rect.y() < 0);
786 }
787
788 Eina_Bool ewk_frame_text_matches_nth_pos_get(const Evas_Object* ewkFrame, size_t number, int* x, int* y)
789 {
790     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
791     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
792
793     Vector<WebCore::IntRect> intRects = smartData->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch);
794
795     /* remove useless values */
796     std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value);
797
798     if (intRects.isEmpty() || number > intRects.size())
799         return false;
800
801     std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than);
802
803     if (x)
804         *x = intRects[number - 1].x();
805     if (y)
806         *y = intRects[number - 1].y();
807     return true;
808 }
809
810 Eina_Bool ewk_frame_stop(Evas_Object* ewkFrame)
811 {
812     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
813     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
814     smartData->frame->loader()->stopAllLoaders();
815     return true;
816 }
817
818 Eina_Bool ewk_frame_reload(Evas_Object* ewkFrame)
819 {
820     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
821     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
822     smartData->frame->loader()->reload();
823     return true;
824 }
825
826 Eina_Bool ewk_frame_reload_full(Evas_Object* ewkFrame)
827 {
828     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
829     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
830     smartData->frame->loader()->reload(true);
831     return true;
832 }
833
834 Eina_Bool ewk_frame_back(Evas_Object* ewkFrame)
835 {
836     return ewk_frame_navigate(ewkFrame, -1);
837 }
838
839 Eina_Bool ewk_frame_forward(Evas_Object* ewkFrame)
840 {
841     return ewk_frame_navigate(ewkFrame, 1);
842 }
843
844 Eina_Bool ewk_frame_load_in_progress(Evas_Object* ewkFrame)
845 {
846 #if ENABLE(TIZEN_LOADING_STATE_CHECK)
847     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
848     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
849     if (smartData->frame->loader()->isLoading())
850         return true;
851     else
852         return false;
853 #else
854     LOG_ERROR("TIZEN_LOADING_STATE_CHECK is disabled. \n");
855     return false;
856 #endif
857 }
858
859 Eina_Bool ewk_frame_navigate(Evas_Object* ewkFrame, int steps)
860 {
861     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
862     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
863     WebCore::Page* page = smartData->frame->page();
864     if (!page->canGoBackOrForward(steps))
865         return false;
866     page->goBackOrForward(steps);
867     return true;
868 }
869
870 Eina_Bool ewk_frame_back_possible(Evas_Object* ewkFrame)
871 {
872     return ewk_frame_navigate_possible(ewkFrame, -1);
873 }
874
875 Eina_Bool ewk_frame_forward_possible(Evas_Object* ewkFrame)
876 {
877     return ewk_frame_navigate_possible(ewkFrame, 1);
878 }
879
880 Eina_Bool ewk_frame_navigate_possible(Evas_Object* ewkFrame, int steps)
881 {
882     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
883     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
884     WebCore::Page* page = smartData->frame->page();
885     return page->canGoBackOrForward(steps);
886 }
887
888 float ewk_frame_page_zoom_get(const Evas_Object* ewkFrame)
889 {
890     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
891     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
892 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
893     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), -1.0);
894     if (smartData->cairoScaling)
895         return smartData->frame->view()->scaleFactor();
896 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
897 #else
898     if (smartData->textZoom)
899         return smartData->frame->textZoomFactor();
900 #endif
901     return smartData->frame->pageZoomFactor();
902 #else
903     return smartData->frame->pageZoomFactor();
904 #endif
905 }
906
907 Eina_Bool ewk_frame_page_zoom_set(Evas_Object* ewkFrame, float pageZoomFactor)
908 {
909     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
910     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
911
912 #if ENABLE(TIZEN_WEBCORE_SELECTIVE_RENDERING)
913     WebCore::FrameView* view = smartData->frame->view();
914     view->clearDelayedUpdateRegions();
915 #endif
916 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
917     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
918     if (smartData->cairoScaling)
919         smartData->frame->view()->setScaleFactor(pageZoomFactor);
920     else {
921 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
922         smartData->frame->setPageZoomFactor(pageZoomFactor);
923 #else
924         if (smartData->textZoom)
925             smartData->frame->setTextZoomFactor(pageZoomFactor);
926         else
927             smartData->frame->setPageZoomFactor(pageZoomFactor);
928 #endif
929     }
930 #else
931     smartData->frame->setPageZoomFactor(pageZoomFactor);
932 #endif
933     return true;
934 }
935
936 float ewk_frame_text_zoom_get(const Evas_Object* ewkFrame)
937 {
938     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
939     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
940     return smartData->frame->textZoomFactor();
941 }
942
943 Eina_Bool ewk_frame_text_zoom_set(Evas_Object* ewkFrame, float textZoomFactor)
944 {
945     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
946     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
947     smartData->frame->setTextZoomFactor(textZoomFactor);
948     return true;
949 }
950
951 /**
952  * Query if zoom uses cairo scaling or not.
953  *
954  * @param ewkFrame frame to query setting.
955  *
956  * @return @c true if should use cairo scaling, @c false otherwise.
957  */
958 Eina_Bool ewk_frame_zoom_cairo_scaling_get(const Evas_Object* ewkFrame)
959 {
960 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
961     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
962     return smartData->cairoScaling;
963 #else
964     return false;
965 #endif
966 }
967
968 /**
969  * Set if zoom should use cairo scaling or not.
970  *
971  * @param ewkFrame frame to change setting.
972  * @param setting @c true if should use cairo scaling,
973                   @c false otherwise.
974  *
975  * @return @c true on success, @c false otherwise.
976  */
977 Eina_Bool ewk_frame_zoom_cairo_scaling_set(Evas_Object* ewkFrame, Eina_Bool setting)
978 {
979 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
980     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
981     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
982     setting = !!setting;
983     if (smartData->cairoScaling == setting)
984         return true;
985
986     smartData->cairoScaling = setting;
987     return true;
988 #else
989     return false;
990 #endif
991 }
992
993 #if ENABLE(TIZEN_HIT_TEST)
994 static void _ewk_frame_hash_data_free_cb(void *data)
995 {
996     EINA_SAFETY_ON_NULL_RETURN(data);
997     free(data);
998 }
999 #endif
1000
1001 void ewk_frame_hit_test_free(Ewk_Hit_Test* hitTest)
1002 {
1003     EINA_SAFETY_ON_NULL_RETURN(hitTest);
1004     eina_stringshare_del(hitTest->title);
1005     eina_stringshare_del(hitTest->alternate_text);
1006     eina_stringshare_del(hitTest->link.text);
1007     eina_stringshare_del(hitTest->link.url);
1008     eina_stringshare_del(hitTest->link.title);
1009     eina_stringshare_del(hitTest->image_uri);
1010     eina_stringshare_del(hitTest->media_uri);
1011 #if ENABLE(TIZEN_HIT_TEST)
1012     eina_hash_free(hitTest->attr_hash);
1013     if (hitTest->image_buffer) {
1014         free(hitTest->image_buffer);
1015         hitTest->image_buffer = 0;
1016     }
1017     eina_stringshare_del(hitTest->tag_name);
1018     eina_stringshare_del(hitTest->node_value);
1019 #endif
1020     free(hitTest);
1021 }
1022
1023 Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* ewkFrame, int x, int y)
1024 {
1025     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1026     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
1027
1028     WebCore::FrameView* view = smartData->frame->view();
1029     EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
1030     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->contentRenderer(), 0);
1031
1032 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
1033     Evas_Coord scrollX, scrollY;
1034     ewk_frame_scroll_pos_get(ewkFrame, &scrollX, &scrollY);
1035 #endif
1036
1037     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame)) {
1038         float zoom = ewk_frame_page_zoom_get(ewkFrame);
1039         x = float(x) / zoom;
1040         y = float(y) / zoom;
1041 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
1042         scrollX = float(scrollX) / zoom;
1043         scrollY = float(scrollY) / zoom;
1044 #endif
1045     }
1046
1047 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
1048     WebCore::CSmartFocus smartFocus(smartData->frame->view());
1049     WebCore::IntPoint smartPoint = smartFocus.getSmartTouchLocation(WebCore::IntPoint(x - scrollX, y - scrollY));
1050     // Modify the given coordinates to the smart point.
1051     x = smartPoint.x() + scrollX;
1052     y = smartPoint.y() + scrollY;
1053 #endif
1054
1055     WebCore::HitTestResult result = smartData->frame->eventHandler()->hitTestResultAtPoint
1056 #if ENABLE(TIZEN_HIT_TEST)
1057                                         // SLP webview passes contents based pos (x, y),
1058                                         // therefore we don't need to call windowToContents()
1059                                         (WebCore::IntPoint(x, y),
1060 #else
1061                                         (view->windowToContents(WebCore::IntPoint(x, y)),
1062 #endif
1063                                         /*allowShadowContent*/ false, /*ignoreClipping*/ true);
1064
1065     if (result.scrollbar())
1066         return 0;
1067     if (!result.innerNode())
1068         return 0;
1069
1070     Ewk_Hit_Test* hitTest = static_cast<Ewk_Hit_Test*>(calloc(1, sizeof(Ewk_Hit_Test)));
1071     if (!hitTest) {
1072         CRITICAL("Could not allocate memory for hit test.");
1073         return 0;
1074     }
1075
1076     hitTest->x = result.point().x();
1077     hitTest->y = result.point().y();
1078 #if ENABLE(TIZEN_SUPPORT_INNERFRAME_FOR_HIT_TEST)
1079     WebCore::Node* innerNode = result.innerNode();
1080     if (innerNode) {
1081         hitTest->bounding_box.x = innerNode->getRect().x();
1082         hitTest->bounding_box.y = innerNode->getRect().y();
1083         hitTest->bounding_box.width = innerNode->getRect().width();
1084         hitTest->bounding_box.height = innerNode->getRect().height();
1085
1086         // add for inner frame
1087         WebCore::Frame* innerFrame = result.innerNode()->document()->frame();
1088         while (innerFrame && innerFrame != smartData->frame) {
1089             WebCore::Node* owner = innerFrame->ownerElement();
1090             if (owner) {
1091                 hitTest->bounding_box.x += owner->getRect().x();
1092                 hitTest->bounding_box.y += owner->getRect().y();
1093                 innerFrame = owner->document()->frame();
1094             } else
1095                 break;
1096         }
1097
1098         // scale bounding_box if cairo scaling
1099         if (ewk_frame_zoom_cairo_scaling_get(ewkFrame)) {
1100             float zoom = ewk_frame_page_zoom_get(ewkFrame);
1101             hitTest->bounding_box.x *= zoom;
1102             hitTest->bounding_box.y *= zoom;
1103             hitTest->bounding_box.width *= zoom;
1104             hitTest->bounding_box.height *= zoom;
1105         }
1106     } else {
1107         hitTest->bounding_box.x = 0;
1108         hitTest->bounding_box.y = 0;
1109         hitTest->bounding_box.width = 0;
1110         hitTest->bounding_box.height = 0;
1111     }
1112 #else
1113     hitTest->bounding_box.x = 0;
1114     hitTest->bounding_box.y = 0;
1115     hitTest->bounding_box.width = 0;
1116     hitTest->bounding_box.height = 0;
1117 #endif // TIZEN_SUPPORT_INNERFRAME_FOR_HIT_TEST)
1118
1119     WebCore::TextDirection direction;
1120     hitTest->title = eina_stringshare_add(result.title(direction).utf8().data());
1121     hitTest->alternate_text = eina_stringshare_add(result.altDisplayString().utf8().data());
1122     if (result.innerNonSharedNode() && result.innerNonSharedNode()->document()
1123         && result.innerNonSharedNode()->document()->frame())
1124         hitTest->frame = EWKPrivate::kitFrame(result.innerNonSharedNode()->document()->frame());
1125
1126     hitTest->link.text = eina_stringshare_add(result.textContent().utf8().data());
1127     hitTest->link.url = eina_stringshare_add(result.absoluteLinkURL().string().utf8().data());
1128     hitTest->link.title = eina_stringshare_add(result.titleDisplayString().utf8().data());
1129     hitTest->link.target_frame = EWKPrivate::kitFrame(result.targetFrame());
1130
1131     hitTest->image_uri = eina_stringshare_add(result.absoluteImageURL().string().utf8().data());
1132     hitTest->media_uri = eina_stringshare_add(result.absoluteMediaURL().string().utf8().data());
1133
1134     int context = EWK_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
1135
1136     if (!result.absoluteLinkURL().isEmpty())
1137         context |= EWK_HIT_TEST_RESULT_CONTEXT_LINK;
1138     if (!result.absoluteImageURL().isEmpty())
1139         context |= EWK_HIT_TEST_RESULT_CONTEXT_IMAGE;
1140     if (!result.absoluteMediaURL().isEmpty())
1141         context |= EWK_HIT_TEST_RESULT_CONTEXT_MEDIA;
1142     if (result.isSelected())
1143         context |= EWK_HIT_TEST_RESULT_CONTEXT_SELECTION;
1144     if (result.isContentEditable())
1145         context |= EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE;
1146
1147 #if ENABLE(TIZEN_HIT_TEST)
1148     if (result.innerNonSharedNode() && result.innerNonSharedNode()->isTextNode())
1149         context |= EWK_HIT_TEST_RESULT_CONTEXT_TEXT;
1150 #endif
1151
1152 #if ENABLE(TIZEN_SUPPORT_PLUGINS)
1153     WebCore::Node* node = result.innerNonSharedNode();
1154     WebCore::Element* element = 0;
1155     if (node && node->isElementNode())
1156         element = static_cast<WebCore::Element*>(node);
1157
1158     if (element && (element->hasTagName(WebCore::HTMLNames::objectTag) || element->hasTagName(WebCore::HTMLNames::embedTag))) {
1159         WebCore::HTMLPlugInElement* pluginElement = static_cast<WebCore::HTMLPlugInElement*>(element);
1160         WebCore::Widget* widget  = pluginElement->pluginWidget();
1161         if (widget && widget->isPluginView()) {
1162             WebCore::PluginView* pluginView = static_cast<WebCore::PluginView*>(widget);
1163             if (pluginView && pluginView->isPluginStarted()) {
1164                 context |= EWK_HIT_TEST_RESULT_CONTENT_PLUGIN;
1165 #if ENABLE(TIZEN_DONT_PAN_OVER_SOME_PLUGINS)
1166                 if (WebCore::PluginView::isPluginHandlingEvents() && pluginView == WebCore::PluginView::currentPluginHandlingEvents())
1167                     // it means that this plugin was previously tapped, and this plugin is handling events
1168                     context |= EWK_HIT_TEST_RESULT_CONTENT_PLUGIN_SELECTED;
1169 #endif
1170             }
1171         }
1172     }
1173 #endif
1174
1175     hitTest->context = static_cast<Ewk_Hit_Test_Result_Context>(context);
1176
1177 #if ENABLE(TIZEN_HIT_TEST)
1178     hitTest->attr_hash = eina_hash_string_superfast_new(_ewk_frame_hash_data_free_cb);
1179     WebCore::NamedNodeMap* namedNodeMap = result.innerNonSharedNode()->attributes();
1180
1181     if (namedNodeMap) {
1182         for (size_t loopIndex = 0; loopIndex < namedNodeMap->length(); loopIndex++) {
1183             WebCore::Attribute* attribute = namedNodeMap->attributeItem(loopIndex);
1184             String hashKey = attribute->name().toString();
1185             String hashValue = attribute->value();
1186             eina_hash_add(hitTest->attr_hash, hashKey.utf8().data(), strdup(hashValue.utf8().data()));
1187         }
1188     }
1189
1190     hitTest->image_buffer = 0;
1191     if (hitTest->context & EWK_HIT_TEST_RESULT_CONTEXT_IMAGE) {
1192         WebCore::Image* hitImage = result.image();
1193         if (hitImage && hitImage->data()) {
1194             unsigned int imageBufferSize = hitImage->data()->size();
1195             if (imageBufferSize > 0) {
1196                 hitTest->image_buffer = calloc(1, imageBufferSize + 1);
1197                 if (hitTest->image_buffer)
1198                     memcpy(hitTest->image_buffer, (void*)hitImage->data()->data(), imageBufferSize);
1199             }
1200         }
1201     }
1202
1203     WebCore::Node* hitNode = result.innerNonSharedNode();
1204
1205     hitTest->node_value = 0;
1206     if (hitNode) {
1207         String nodeValue = hitNode->nodeValue();
1208         if (!nodeValue.isEmpty())
1209             hitTest->node_value = eina_stringshare_add(nodeValue.utf8().data());
1210     }
1211
1212     WebCore::Element* hitElement = 0;
1213     if (hitNode && hitNode->isElementNode())
1214         hitElement = static_cast<WebCore::Element*>(hitNode);
1215
1216     if (hitElement && !hitElement->tagName().isEmpty())
1217         hitTest->tag_name = eina_stringshare_add(hitElement->tagName().utf8().data());
1218     else
1219         hitTest->tag_name = 0;
1220 #endif
1221
1222     return hitTest;
1223 }
1224
1225 Eina_Bool
1226 ewk_frame_scroll_add(Evas_Object* ewkFrame, int deltaX, int deltaY)
1227 {
1228     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1229     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1230     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1231 #if ENABLE(TIZEN_WEAK_SCROLL)
1232     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->view, false);
1233     if (ewk_frame_weak_scroll_enabled_get(ewkFrame))
1234     {
1235         int vw, vh, sx, sy, sdx, sdy, fw, fh;
1236         ewk_frame_visible_content_geometry_get(ewkFrame, false, 0, 0, &vw, &vh);
1237         ewk_frame_scroll_pos_get(ewkFrame, &sx, &sy);
1238         ewk_frame_contents_size_get(ewkFrame, &fw, &fh);
1239         float zoom = 1.0f;
1240 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1241         if (ewk_frame_zoom_cairo_scaling_get(ewkFrame))
1242             zoom = ewk_frame_page_zoom_get(ewkFrame);
1243 #endif
1244
1245         if (sx + deltaX < 0)
1246             // Reached left bound.
1247             sdx = -sx;
1248         else if (deltaX > fw * zoom - sx - vw * zoom)
1249             // Reached right bound.
1250             sdx = fw * zoom - sx - vw * zoom;
1251         else
1252             sdx = deltaX;
1253
1254         if (sy + deltaY < 0)
1255             // Reached top bound.
1256             sdy = -sy;
1257         else if (deltaY > fh * zoom - sy - vh * zoom)
1258             // Reached bottom bound.
1259             sdy = fh * zoom - sy - vh * zoom;
1260         else
1261             sdy = deltaY;
1262
1263         smartData->weakScroll.dx += sdx;
1264         smartData->weakScroll.dy += sdy;
1265
1266         if (sdx || sdy)
1267             ewk_view_scroll(smartData->view, -sdx, -sdy, 0, 0, vw, vh, 0, 0, vw, vh, true);
1268
1269         return true;
1270     }
1271 #endif
1272
1273 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL)
1274     bool verticalScroll = false, horizontalScroll = false;
1275     WebCore::ScrollDirection direction;
1276     WebCore::ScrollGranularity granularity = WebCore::ScrollByPixel;
1277     float multiplier = 0;
1278
1279     // vertical scroll
1280     if (deltaY) {
1281         direction = deltaY < 0 ? WebCore::ScrollUp : WebCore::ScrollDown;
1282         multiplier = deltaY < 0 ? -deltaY : deltaY;
1283         horizontalScroll = smartData->frame->eventHandler()->scrollOverflowWithMultiplier(direction, granularity, multiplier);
1284     }
1285
1286     // horizontal scroll
1287     if (deltaX) {
1288         direction = deltaX < 0 ? WebCore::ScrollLeft : WebCore::ScrollRight;
1289         multiplier = deltaX < 0 ? -deltaX : deltaX;
1290         verticalScroll = smartData->frame->eventHandler()->scrollOverflowWithMultiplier(direction, granularity, multiplier);
1291     }
1292
1293     if (verticalScroll || horizontalScroll)
1294         return false;
1295 #endif
1296     smartData->frame->view()->scrollBy(WebCore::IntSize(deltaX, deltaY));
1297     return true;
1298 }
1299
1300 /**
1301  * Generate onscroll event on demand
1302  *
1303  * @param ewkFrame frame object to scroll.
1304  *
1305  * @return @c true if possible, @c false otherwise.
1306  */
1307 Eina_Bool
1308 ewk_frame_onscroll_event_generate(Evas_Object* ewkFrame)
1309 {
1310 #if ENABLE(TIZEN_ONSCROLL_EVENT_SUPPRESSION)
1311     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1312     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1313     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1314
1315     WebCore::Document* document = smartData->frame->document();
1316     if (document)
1317         document->eventQueue()->enqueueOrDispatchScrollEvent(document, WebCore::DocumentEventQueue::ScrollEventElementTarget);
1318
1319     return true;
1320 #else
1321     LOG_ERROR("TIZEN_ONSCROLL_EVENT_SUPPRESSION is disabled. \n");
1322     return false;
1323 #endif
1324 }
1325
1326 Eina_Bool
1327 ewk_frame_scroll_set(Evas_Object* ewkFrame, int x, int y)
1328 {
1329     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1330     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1331     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1332 #if ENABLE(TIZEN_WEAK_SCROLL)
1333     smartData->weakScroll.dx = 0;
1334     smartData->weakScroll.dy = 0;
1335 #endif
1336     smartData->frame->view()->setScrollPosition(WebCore::IntPoint(x, y));
1337     return true;
1338 }
1339
1340 Eina_Bool ewk_frame_weak_scroll_enabled_get(const Evas_Object* ewkFrame)
1341 {
1342 #if ENABLE(TIZEN_WEAK_SCROLL)
1343     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1344     return smartData->weakScroll.enabled;
1345 #else
1346     return false;
1347 #endif
1348 }
1349
1350 Eina_Bool ewk_frame_weak_scroll_enabled_set(Evas_Object* ewkFrame, Eina_Bool setting)
1351 {
1352 #if ENABLE(TIZEN_WEAK_SCROLL)
1353     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1354     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1355     setting = !!setting;
1356     if (smartData->weakScroll.enabled == setting)
1357         return true;
1358
1359     if (!setting)
1360     {
1361         // We have just finished weak scrolling so we have to pass scrolls requests
1362         // that were missed during weak scrolling. We need to avoid moving viewport in this case.
1363         smartData->weakScroll.movingViewport = false;
1364         smartData->frame->view()->scrollBy(WebCore::IntSize(smartData->weakScroll.dx, smartData->weakScroll.dy));
1365     }
1366
1367     smartData->weakScroll.movingViewport = true;
1368     smartData->weakScroll.dx = 0;
1369     smartData->weakScroll.dy = 0;
1370     smartData->weakScroll.enabled = setting;
1371
1372     return true;
1373 #else
1374     return false;
1375 #endif
1376 }
1377
1378 Eina_Bool ewk_frame_weak_scroll_moving_viewport_get(Evas_Object* ewkFrame)
1379 {
1380 #if ENABLE(TIZEN_WEAK_SCROLL)
1381     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1382     return smartData->weakScroll.movingViewport;
1383 #else
1384     return true;
1385 #endif
1386 }
1387
1388 /**
1389  * Gets the possible scroll size of the given frame.
1390  *
1391  * Possible scroll size is contents size minus the viewport
1392  * size. It's the last allowed value for ewk_frame_scroll_set()
1393  *
1394  * @param ewkFrame frame object to get scroll size
1395  * @param width the pointer to store the horizontal size that is possible to scroll,
1396  *        may be @c 0
1397  * @param height the pointer to store the vertical size that is possible to scroll,
1398  *        may be @c 0
1399  *
1400  * @return @c true on success, @c false otherwise and
1401  *         values are zeroed
1402  */
1403 Eina_Bool
1404 ewk_frame_scroll_size_get(const Evas_Object* ewkFrame, int* width, int* height)
1405 {
1406     if (width)
1407         *width = 0;
1408     if (height)
1409         *height = 0;
1410     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1411     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1412     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1413     WebCore::IntPoint point = smartData->frame->view()->maximumScrollPosition();
1414     if (width)
1415         *width = point.x();
1416     if (height)
1417         *height = point.y();
1418     return true;
1419 }
1420
1421 Eina_Bool
1422 ewk_frame_scroll_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
1423 {
1424     if (x)
1425         *x = 0;
1426     if (y)
1427         *y = 0;
1428     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1429     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1430     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1431 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1432     WebCore::IntPoint pos = smartData->frame->view()->visibleContentRect(false, false).location();
1433 #else
1434     WebCore::IntPoint pos = smartData->frame->view()->scrollPosition();
1435 #endif
1436     if (x)
1437         *x = pos.x();
1438     if (y)
1439         *y = pos.y();
1440 #if ENABLE(TIZEN_WEAK_SCROLL)
1441     if (ewk_frame_weak_scroll_enabled_get(ewkFrame))
1442     {
1443         if (x)
1444             *x += smartData->weakScroll.dx;
1445         if (y)
1446             *y += smartData->weakScroll.dy;
1447     }
1448 #endif
1449     return true;
1450 }
1451
1452 /**
1453  * Get the current scroll scaled position of given frame.
1454  *
1455  * @param ewkFrame frame object to scroll.
1456  * @param x where to return horizontal position. May be @c NULL.
1457  * @param y where to return vertical position. May be @c NULL.
1458  *
1459  * @return @c true if possible, @c false otherwise and
1460  *         values are zeroed.
1461  */
1462 Eina_Bool
1463 ewk_frame_scroll_scaled_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
1464 {
1465 #if ENABLE(TIZEN_SCROLL_SCALED_POS_GET)
1466     if (!ewk_frame_scroll_pos_get(ewkFrame, x, y))
1467         return false;
1468
1469     float zoom = ewk_frame_page_zoom_get(ewkFrame);
1470
1471     if (x)
1472         *x *= zoom;
1473     if (y)
1474         *y *= zoom;
1475
1476     return true;
1477 #else
1478     return false;
1479 #endif
1480 }
1481
1482 Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* ewkFrame, Eina_Bool includeScrollbars, int* x, int* y, int* width, int* height)
1483 {
1484     if (x)
1485         *x = 0;
1486     if (y)
1487         *y = 0;
1488     if (width)
1489         *width = 0;
1490     if (height)
1491         *height = 0;
1492     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1493     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1494     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1495     WebCore::IntRect rect = smartData->frame->view()->visibleContentRect(includeScrollbars);
1496     if (x)
1497         *x = rect.x();
1498     if (y)
1499         *y = rect.y();
1500     if (width)
1501         *width = rect.width();
1502     if (height)
1503         *height = rect.height();
1504     return true;
1505 }
1506
1507 /**
1508  * Get the current frame visible content geometry without considering the
1509  * current scale level.
1510  *
1511  * @param ewkFrame frame object to query visible content geometry.
1512  * @param include_scrollbars whenever to include scrollbars size.
1513  * @param x horizontal position. May be @c NULL.
1514  * @param y vertical position. May be @c NULL.
1515  * @param width width. May be @c NULL.
1516  * @param height height. May be @c NULL.
1517  *
1518  * @return @c true if possible, @c false otherwise and
1519  *         values are zeroed.
1520  */
1521 Eina_Bool ewk_frame_visible_content_geometry_unscaled_get(const Evas_Object* ewkFrame, Eina_Bool include_scrollbars, int* x, int* y, int* width, int* height)
1522 {
1523 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1524     if (x)
1525         *x = 0;
1526     if (y)
1527         *y = 0;
1528     if (width)
1529         *width = 0;
1530     if (height)
1531         *height = 0;
1532     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1533     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1534     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1535     WebCore::IntRect rect = smartData->frame->view()->visibleContentRect(include_scrollbars, false);
1536     if (x)
1537         *x = rect.x();
1538     if (y)
1539         *y = rect.y();
1540     if (width)
1541         *width = rect.width();
1542     if (height)
1543         *height = rect.height();
1544     return true;
1545 #else
1546     return false;
1547 #endif
1548 }
1549
1550 Eina_Bool ewk_frame_paint_full_get(const Evas_Object* ewkFrame)
1551 {
1552     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1553     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1554     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), false);
1555     return smartData->frame->view()->paintsEntireContents();
1556 }
1557
1558 void ewk_frame_paint_full_set(Evas_Object* ewkFrame, Eina_Bool flag)
1559 {
1560     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1561     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
1562     EINA_SAFETY_ON_NULL_RETURN(smartData->frame->view());
1563     smartData->frame->view()->setPaintsEntireContents(flag);
1564 }
1565
1566 Eina_Bool ewk_frame_feed_focus_in(Evas_Object* ewkFrame)
1567 {
1568     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1569     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1570     WebCore::FocusController* c = smartData->frame->page()->focusController();
1571     c->setFocusedFrame(smartData->frame);
1572
1573     c->setActive(true);
1574     c->setFocused(true);
1575     return true;
1576 }
1577
1578 Eina_Bool ewk_frame_feed_focus_out(Evas_Object* ewkFrame)
1579 {
1580     // TODO: what to do on focus out?
1581     ERR("what to do?");
1582     return false;
1583 }
1584
1585 Eina_Bool ewk_frame_focused_element_geometry_get(const Evas_Object *ewkFrame, int *x, int *y, int *w, int *h)
1586 {
1587     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1588     WebCore::Document* document = smartData->frame->document();
1589     if (!document)
1590         return false;
1591     WebCore::Node* focusedNode = document->focusedNode();
1592     if (!focusedNode)
1593         return false;
1594     WebCore::IntRect nodeRect = focusedNode->getRect();
1595     if (x)
1596         *x = nodeRect.x();
1597     if (y)
1598         *y = nodeRect.y();
1599     if (w)
1600         *w = nodeRect.width();
1601     if (h)
1602         *h = nodeRect.height();
1603     return true;
1604 }
1605
1606 Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* ewkFrame, const Evas_Event_Mouse_Wheel* wheelEvent)
1607 {
1608     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1609     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1610     EINA_SAFETY_ON_NULL_RETURN_VAL(wheelEvent, false);
1611
1612     WebCore::FrameView* view = smartData->frame->view();
1613     DBG("ewkFrame=%p, view=%p, direction=%d, z=%d, pos=%d,%d",
1614         ewkFrame, view, wheelEvent->direction, wheelEvent->z, wheelEvent->canvas.x, wheelEvent->canvas.y);
1615     EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);
1616
1617 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1618     Evas_Coord x, y;
1619     evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1620
1621     float zoom = 1.0;
1622     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame))
1623         zoom = ewk_frame_page_zoom_get(ewkFrame);
1624
1625     Evas_Event_Mouse_Wheel ev1 = *wheelEvent;
1626     ev1.canvas.x = ev1.canvas.x / zoom;
1627     ev1.canvas.y = ev1.canvas.y / zoom;
1628
1629     WebCore::PlatformWheelEvent event(&ev1, WebCore::IntPoint(x / zoom, y / zoom));
1630 #else
1631     WebCore::PlatformWheelEvent event(wheelEvent);
1632 #endif
1633     return smartData->frame->eventHandler()->handleWheelEvent(event);
1634 }
1635
1636 Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* ewkFrame, const Evas_Event_Mouse_Down* downEvent)
1637 {
1638     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1639     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1640     EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, false);
1641
1642     WebCore::FrameView* view = smartData->frame->view();
1643     DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
1644         ewkFrame, view, downEvent->button, downEvent->canvas.x, downEvent->canvas.y);
1645     EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);
1646
1647     Evas_Coord x, y;
1648     evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1649
1650 #if ENABLE(TIZEN_ISF_PORT)
1651     smartData->frame->page()->editorClient()->handleInputMethodMousePress();
1652 #endif
1653
1654 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1655     float zoom = 1.0;
1656     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame))
1657         zoom = ewk_frame_page_zoom_get(ewkFrame);
1658
1659     Evas_Event_Mouse_Down ev1 = *downEvent;
1660     ev1.canvas.x = ev1.canvas.x / zoom;
1661     ev1.canvas.y = ev1.canvas.y / zoom;
1662
1663 #if ENABLE(TIZEN_SMART_FOCUSING)
1664     WebCore::CSmartFocus smartFocus(smartData->frame->view());
1665     WebCore::IntPoint wndPoint(ev1.canvas.x - x / zoom, ev1.canvas.y - y / zoom);
1666     // Pass wndPoint and receive window based smart_point
1667     WebCore::IntPoint smart_point = smartFocus.getSmartTouchLocation(wndPoint);
1668     smart_point.move(x / zoom, y / zoom);
1669
1670     ev1.canvas.x = smart_point.x();
1671     ev1.canvas.y = smart_point.y();
1672 #endif // TIZEN_SMART_FOCUSING
1673
1674     WebCore::PlatformMouseEvent event(&ev1, WebCore::IntPoint(x / zoom, y / zoom));
1675 #else
1676     WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
1677 #endif
1678     return smartData->frame->eventHandler()->handleMousePressEvent(event);
1679 }
1680
1681 Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* ewkFrame, const Evas_Event_Mouse_Up* upEvent)
1682 {
1683     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1684     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1685     EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, false);
1686
1687     WebCore::FrameView* view = smartData->frame->view();
1688     DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
1689         ewkFrame, view, upEvent->button, upEvent->canvas.x, upEvent->canvas.y);
1690     EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);
1691
1692     Evas_Coord x, y;
1693     evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1694
1695 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1696     float zoom = 1.0;
1697     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame))
1698         zoom = ewk_frame_page_zoom_get(ewkFrame);
1699
1700     Evas_Event_Mouse_Up ev1 = *upEvent;
1701     ev1.canvas.x = ev1.canvas.x / zoom;
1702     ev1.canvas.y = ev1.canvas.y / zoom;
1703
1704 #if ENABLE(TIZEN_SMART_FOCUSING)
1705     WebCore::CSmartFocus smartFocus(smartData->frame->view());
1706     WebCore::IntPoint wndPoint(ev1.canvas.x - x / zoom, ev1.canvas.y - y / zoom);
1707     // Pass wndPoint and receive window based smart_point
1708     WebCore::IntPoint smart_point = smartFocus.getSmartTouchLocation(wndPoint);
1709     smart_point.move(x / zoom, y / zoom);
1710
1711     ev1.canvas.x = smart_point.x();
1712     ev1.canvas.y = smart_point.y();
1713 #endif // TIZEN_SMART_FOCUSING
1714
1715     WebCore::PlatformMouseEvent event(&ev1, WebCore::IntPoint(x / zoom, y / zoom));
1716 #else
1717     WebCore::PlatformMouseEvent event(upEvent, WebCore::IntPoint(x, y));
1718 #endif
1719
1720 #if ENABLE(TIZEN_SUPPORT_PLUGINS) && ENABLE(TIZEN_DONT_PAN_OVER_SOME_PLUGINS)
1721
1722     if (WebCore::PluginView::isPluginHandlingEvents() && WebCore::PluginView::currentPluginHandlingEvents())
1723         return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1724
1725 #endif
1726 #if ENABLE(TIZEN_ISF_PORT)
1727     Eina_Bool result = smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1728     smartData->frame->page()->editorClient()->handleInputMethodMouseRelease();
1729     return result;
1730 #else
1731     return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1732 #endif
1733 }
1734
1735 Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* ewkFrame, const Evas_Event_Mouse_Move* moveEvent)
1736 {
1737     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1738     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1739     EINA_SAFETY_ON_NULL_RETURN_VAL(moveEvent, false);
1740
1741     WebCore::FrameView* view = smartData->frame->view();
1742     DBG("ewkFrame=%p, view=%p, pos: old=%d,%d, new=%d,%d, buttons=%d",
1743         ewkFrame, view, moveEvent->cur.canvas.x, moveEvent->cur.canvas.y,
1744         moveEvent->prev.canvas.x, moveEvent->prev.canvas.y, moveEvent->buttons);
1745     EINA_SAFETY_ON_NULL_RETURN_VAL(view, false);
1746
1747     Evas_Coord x, y;
1748     evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1749
1750 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1751     float zoom = 1.0;
1752     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame))
1753         zoom = ewk_frame_page_zoom_get(ewkFrame);
1754
1755     Evas_Event_Mouse_Move ev1 = *moveEvent;
1756     ev1.cur.canvas.x = ev1.cur.canvas.x / zoom;
1757     ev1.cur.canvas.y = ev1.cur.canvas.y / zoom;
1758     WebCore::PlatformMouseEvent event(&ev1, WebCore::IntPoint(x / zoom, y / zoom));
1759 #else
1760     WebCore::PlatformMouseEvent event(moveEvent, WebCore::IntPoint(x, y));
1761 #endif
1762     return smartData->frame->eventHandler()->mouseMoved(event);
1763 }
1764
1765 Eina_Bool ewk_frame_feed_touch_event(Evas_Object* ewkFrame, Ewk_Touch_Event_Type action, Eina_List* points, int metaState)
1766 {
1767     Eina_Bool result = false;
1768
1769 #if ENABLE(TOUCH_EVENTS)
1770     EINA_SAFETY_ON_NULL_RETURN_VAL(points, false);
1771     EWK_FRAME_SD_GET(ewkFrame, smartData);
1772
1773 #if ENABLE(TIZEN_PLUGIN_SNPEVENT)
1774     if (!smartData || !smartData->frame
1775             || (!ewk_view_need_touch_events_get(smartData->view) && (!WebCore::PluginView::isPluginHandlingEvents() || !WebCore::PluginView::currentPluginHandlingEvents()))
1776        ) {
1777 #else
1778     if (!smartData || !smartData->frame || !ewk_view_need_touch_events_get(smartData->view)) {
1779 #endif
1780         void *point;
1781         EINA_LIST_FREE(points, point);
1782         return EINA_FALSE;
1783     }
1784
1785     Evas_Coord x, y;
1786     evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1787
1788     WebCore::TouchEventType type = WebCore::TouchStart;
1789     switch (action) {
1790     case EWK_TOUCH_START:
1791         type = WebCore::TouchStart;
1792         break;
1793     case EWK_TOUCH_END:
1794         type = WebCore::TouchEnd;
1795         break;
1796     case EWK_TOUCH_MOVE:
1797         type = WebCore::TouchMove;
1798         break;
1799     case EWK_TOUCH_CANCEL:
1800         type = WebCore::TouchCancel;
1801         break;
1802     default:
1803         return false;
1804     }
1805
1806 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
1807     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame)) {
1808         float zoom = ewk_frame_page_zoom_get(ewkFrame);
1809         Eina_List* l;
1810         void* pnt;
1811
1812         EINA_LIST_FOREACH(points, l, pnt) {
1813             ((Ewk_Touch_Point*)pnt)->x /= zoom;
1814             ((Ewk_Touch_Point*)pnt)->y /= zoom;
1815         }
1816         x /= zoom;
1817         y /= zoom;
1818     }
1819 #endif
1820
1821     WebCore::PlatformTouchEvent te(points, WebCore::IntPoint(x, y), type, metaState);
1822     result = smartData->frame->eventHandler()->handleTouchEvent(te);
1823 #endif
1824     return result;
1825 }
1826
1827 static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent& keyEvent)
1828 {
1829     WebCore::ScrollDirection direction;
1830     WebCore::ScrollGranularity granularity;
1831
1832     int keyCode = keyEvent.windowsVirtualKeyCode();
1833
1834     switch (keyCode) {
1835     case VK_SPACE:
1836         granularity = WebCore::ScrollByPage;
1837         if (keyEvent.shiftKey())
1838             direction = WebCore::ScrollUp;
1839         else
1840             direction = WebCore::ScrollDown;
1841         break;
1842     case VK_NEXT:
1843         granularity = WebCore::ScrollByPage;
1844         direction = WebCore::ScrollDown;
1845         break;
1846     case VK_PRIOR:
1847         granularity = WebCore::ScrollByPage;
1848         direction = WebCore::ScrollUp;
1849         break;
1850     case VK_HOME:
1851         granularity = WebCore::ScrollByDocument;
1852         direction = WebCore::ScrollUp;
1853         break;
1854     case VK_END:
1855         granularity = WebCore::ScrollByDocument;
1856         direction = WebCore::ScrollDown;
1857         break;
1858     case VK_LEFT:
1859         granularity = WebCore::ScrollByLine;
1860         direction = WebCore::ScrollLeft;
1861         break;
1862     case VK_RIGHT:
1863         granularity = WebCore::ScrollByLine;
1864         direction = WebCore::ScrollRight;
1865         break;
1866     case VK_UP:
1867         direction = WebCore::ScrollUp;
1868         if (keyEvent.ctrlKey())
1869             granularity = WebCore::ScrollByDocument;
1870         else
1871             granularity = WebCore::ScrollByLine;
1872         break;
1873     case VK_DOWN:
1874         direction = WebCore::ScrollDown;
1875         if (keyEvent.ctrlKey())
1876             granularity = WebCore::ScrollByDocument;
1877         else
1878             granularity = WebCore::ScrollByLine;
1879         break;
1880     default:
1881         return false;
1882     }
1883
1884     if (frame->eventHandler()->scrollOverflow(direction, granularity))
1885         return false;
1886
1887     frame->view()->scroll(direction, granularity);
1888     return true;
1889 }
1890
1891 Eina_Bool ewk_frame_feed_key_down(Evas_Object* ewkFrame, const Evas_Event_Key_Down* downEvent)
1892 {
1893     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1894     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1895     EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, false);
1896
1897     DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1898         ewkFrame, downEvent->keyname, downEvent->key ? downEvent->key : "", downEvent->string ? downEvent->string : "");
1899
1900     WebCore::PlatformKeyboardEvent event(downEvent);
1901     if (smartData->frame->eventHandler()->keyEvent(event))
1902         return true;
1903
1904     return _ewk_frame_handle_key_scrolling(smartData->frame, event);
1905 }
1906
1907 Eina_Bool ewk_frame_feed_key_up(Evas_Object* ewkFrame, const Evas_Event_Key_Up* upEvent)
1908 {
1909     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1910     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
1911     EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, false);
1912
1913     DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1914         ewkFrame, upEvent->keyname, upEvent->key ? upEvent->key : "", upEvent->string ? upEvent->string : "");
1915
1916     WebCore::PlatformKeyboardEvent event(upEvent);
1917     return smartData->frame->eventHandler()->keyEvent(event);
1918 }
1919
1920 Ewk_Text_Selection_Type ewk_frame_text_selection_type_get(const Evas_Object* ewkFrame)
1921 {
1922     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EWK_TEXT_SELECTION_NONE);
1923     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EWK_TEXT_SELECTION_NONE);
1924
1925     WebCore::FrameSelection* controller = smartData->frame->selection();
1926     if (!controller)
1927         return EWK_TEXT_SELECTION_NONE;
1928
1929     switch (controller->selectionType()) {
1930     case WebCore::VisibleSelection::CaretSelection:
1931         return EWK_TEXT_SELECTION_CARET;
1932     case WebCore::VisibleSelection::RangeSelection:
1933         return EWK_TEXT_SELECTION_RANGE;
1934     default:
1935         return EWK_TEXT_SELECTION_NONE;
1936     }
1937 }
1938
1939 /* internal methods ****************************************************/
1940
1941 /**
1942  * @internal
1943  * Allows access to the local storage of WebKit.
1944  *
1945  * @param ewkFrame frame.
1946  * @param exception_code if there was any problem with access to the local storage
1947  */
1948 WebCore::Storage* _ewk_frame_local_storage_get(Evas_Object* ewkFrame, WebCore::ExceptionCode* exception_code)
1949 {
1950 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
1951     WebCore::Frame* frame = 0;
1952     WebCore::DOMWindow* dom_window = 0;
1953
1954     frame = ewk_frame_core_get(ewkFrame);
1955     if (!frame)
1956         return 0;
1957
1958     dom_window = frame->domWindow();
1959     if (!dom_window)
1960         return 0;
1961
1962     return dom_window->localStorage(*exception_code);
1963 #else
1964     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
1965     return 0;
1966 #endif
1967 }
1968
1969 /**
1970  * Returns the number of pairs (key/value) currently present in the local storage
1971  *
1972  * @return the number of pairs (key/value) currently present in the local storage.
1973  */
1974 unsigned ewk_frame_local_storage_size(Evas_Object* ewkFrame)
1975 {
1976 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
1977     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, 0);
1978     WebCore::ExceptionCode exception_code = 0;
1979     WebCore::Storage* storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
1980     if (!storage || exception_code)
1981         return 0;
1982     return storage->length();
1983 #else
1984     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
1985     return 0;
1986 #endif
1987 }
1988
1989 /**
1990  * Returns the name of the key in the local storage.
1991  *
1992  * @param ewkFrame frame
1993  * @param index index in the local storage
1994  *
1995  * @return the name of the key in the local storage or @c NULL if the given index doesn't exist or other error occurred. The return value SHOULD be freed after use.
1996  */
1997 char* ewk_frame_local_storage_key_get(Evas_Object* ewkFrame, unsigned index)
1998 {
1999 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
2000     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, 0);
2001     WebCore::ExceptionCode exception_code = 0;
2002     WebCore::Storage* storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
2003     if (!storage || exception_code)
2004         return 0;
2005
2006     if (index >= storage->length())
2007         return 0;
2008
2009     WTF::String key = storage->key(index);
2010     return key.isNull() ? 0 : strdup(key.utf8().data());
2011 #else
2012     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
2013     return 0;
2014 #endif
2015 }
2016
2017 /**
2018  * Returns the value associated with the given key.
2019  *
2020  * @param ewkFrame frame
2021  * @param key the key in the local storage
2022  *
2023  * @return the value associated with the given key or NULL if the given key doesn't exist or other error occurred. The return value SHOULD be freed after use.
2024  */
2025 char* ewk_frame_local_storage_item_get(Evas_Object* ewkFrame, const char* key)
2026 {
2027 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
2028     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, 0);
2029     WebCore::ExceptionCode exception_code = 0;
2030     WebCore::Storage* storage = 0;
2031
2032     if (!key)
2033         return 0;
2034
2035     storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
2036     if (!storage || exception_code)
2037         return 0;
2038
2039     WTF::String value = storage->getItem(key);
2040     return value.isNull() ? 0 : strdup(value.utf8().data());
2041 #else
2042     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
2043     return 0;
2044 #endif
2045 }
2046
2047 /**
2048  * Sets a pair(key/value) given through param to the local storage.
2049  *
2050  * @param ewkFrame frame
2051  * @param key the name of the key
2052  * @param value value associated with the key
2053  * @param err err > 0 if there was any problem with saving the new pair, possible values: no modifications allowed or quota exceeded
2054  * @param flag possible values 1 - the new pair has a read only attribute, 0 - hasn't.
2055  *
2056  * @return true if the new pair has been added to the local storage, false otherwise.
2057  */
2058 Eina_Bool ewk_frame_local_storage_item_set(Evas_Object* ewkFrame, const char* key, const char* value, unsigned* err, int flag)
2059 {
2060 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
2061     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, false);
2062     WebCore::ExceptionCode exception_code = 0;
2063     WebCore::Storage* storage = 0;
2064
2065     if (!key || !value) {
2066         if (err)
2067             *err = WebCore::INVALID_CHARACTER_ERR;
2068         return false;
2069     }
2070
2071     storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
2072     if (!storage || exception_code) {
2073         if (err)
2074             *err = (unsigned) exception_code;
2075         return false;
2076
2077     }
2078
2079     storage->setItem(key, WTF::String::fromUTF8(value), exception_code, Eina_Bool(flag));
2080     if (exception_code) {
2081         if (err)
2082             *err = (unsigned) exception_code;
2083         return false;
2084     }
2085
2086     if (err)
2087         *err = 0;
2088     return true;
2089 #else
2090     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
2091     return false;
2092 #endif
2093 }
2094
2095 /**
2096  * Removes a pair(key, value) from the local storage.
2097  *
2098  * @param ewkFrame frame
2099  * @param key the name of the key
2100  * @param err err > 0 if there was any problem with removing the pair, possible values: no modifications allowed or quota exceeded
2101  *
2102  * @return true if the new pair has been removed from the local storage, false otherwise.
2103  */
2104 Eina_Bool ewk_frame_local_storage_item_remove(Evas_Object* ewkFrame, const char* key, unsigned* err)
2105 {
2106 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
2107     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, false);
2108     WebCore::ExceptionCode exception_code = 0;
2109     WebCore::Storage* storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
2110     if (!key || !storage || exception_code)
2111         return false;
2112
2113     storage->removeItem(key, &exception_code);
2114
2115     if (exception_code) {
2116         if (err)
2117             *err = exception_code;
2118         return false;
2119     }
2120     if (err)
2121         *err = 0;
2122     return true;
2123 #else
2124     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
2125     return false;
2126 #endif
2127 }
2128
2129 /**
2130  * Clears the pairs from the local storage.
2131  *
2132  * @param ewkFrame frame
2133  * @param flag possible values 1 - all pairs are removed (with read only attributes too), 0 - only the pairs without read only attributes are removed
2134  */
2135 Eina_Bool ewk_frame_local_storage_clear(Evas_Object* ewkFrame, int flag)
2136 {
2137 #if ENABLE(TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION)
2138     EINA_SAFETY_ON_NULL_RETURN_VAL(ewkFrame, false);
2139     WebCore::ExceptionCode exception_code = 0;
2140     WebCore::Storage* storage = _ewk_frame_local_storage_get(ewkFrame, &exception_code);
2141     if (!storage || exception_code)
2142         return false;
2143
2144     storage->clear((Eina_Bool) flag);
2145     return true;
2146 #else
2147     LOG_ERROR("TIZEN_LOCAL_STORAGE_READ_ONLY_EXTENSION is disabled. \n");
2148     return false;
2149 #endif
2150 }
2151
2152 /**
2153  * @internal
2154  * Reports that editor client selection was changed.
2155  *
2156  * Emits signal: "editorclient,selection,changed" with no parameters.
2157  * @param ewkFrame Frame
2158  *
2159  * Emits signal: "editorclientselection,changed" with no parameters.
2160  */
2161 void ewk_frame_editor_client_selection_changed(Evas_Object* ewkFrame)
2162 {
2163     evas_object_smart_callback_call(ewkFrame, "editorclient,selection,changed", 0);
2164     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2165     ewk_view_editor_client_selection_changed(smartData->view);
2166 }
2167
2168 /**
2169  * @internal
2170  * Reports that editor client's contents were changed.
2171  *
2172  * @param ewkFrame Frame
2173  *
2174  * Emits signal: "editorclient,contents,changed" with no parameters.
2175  */
2176 void ewk_frame_editor_client_contents_changed(Evas_Object* ewkFrame)
2177 {
2178     evas_object_smart_callback_call(ewkFrame, "editorclient,contents,changed", 0);
2179     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2180     ewk_view_editor_client_contents_changed(smartData->view);
2181 }
2182
2183 /**
2184  * @internal
2185  * Reports that editor client begins editing.
2186  *
2187  * Emits signal: "editorclient,editing,started" with no parameters.
2188  */
2189 void ewk_frame_editor_client_editing_started(Evas_Object* ewkFrame)
2190 {
2191 #if ENABLE(TIZEN_EDITOR_CLIENT)
2192     evas_object_smart_callback_call(ewkFrame, "editorclient,editing,started", 0);
2193     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2194     ewk_view_editor_client_editing_started(smartData->view);
2195 #else
2196     LOG_ERROR("TIZEN_EDITOR_CLIENT is disabled. \n");
2197 #endif
2198 }
2199
2200 /**
2201  * @internal
2202  * Reports that editor client finishes editing.
2203  *
2204  * Emits signal: "editorclient,editing,finished" with no parameters.
2205  */
2206 void ewk_frame_editor_client_editing_finished(Evas_Object* ewkFrame)
2207 {
2208 #if ENABLE(TIZEN_EDITOR_CLIENT)
2209     evas_object_smart_callback_call(ewkFrame, "editorclient,editing,finished", 0);
2210     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2211     ewk_view_editor_client_editing_finished(smartData->view);
2212 #else
2213     LOG_ERROR("TIZEN_EDITOR_CLIENT is disabled. \n");
2214 #endif
2215 }
2216
2217 /**
2218  * @internal
2219  *
2220  * Creates a new EFL WebKit Frame object.
2221  *
2222  * Frames are low level entries contained in a page that is contained
2223  * by a view. Usually one operates on the view and not directly on the
2224  * frame.
2225  *
2226  * @param canvas canvas where to create the frame object
2227  *
2228  * @return a new frame object or @c 0 on failure
2229  */
2230 Evas_Object* ewk_frame_add(Evas* canvas)
2231 {
2232     return evas_object_smart_add(canvas, _ewk_frame_smart_class_new());
2233 }
2234
2235 /**
2236  * @internal
2237  *
2238  * Initialize frame based on actual WebKit frame.
2239  *
2240  * This is internal and should never be called by external users.
2241  */
2242 bool ewk_frame_init(Evas_Object* ewkFrame, Evas_Object* view, WebCore::Frame* frame)
2243 {
2244     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
2245     if (!smartData->frame) {
2246         WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(frame);
2247         frameLoaderClient->setWebFrame(ewkFrame);
2248         smartData->frame = frame;
2249         smartData->view = view;
2250         frame->init();
2251         return true;
2252     }
2253
2254     ERR("frame %p already set for %p, ignored new %p",
2255         smartData->frame, ewkFrame, frame);
2256     return false;
2257 }
2258
2259 /**
2260  * @internal
2261  *
2262  * Adds child to the frame.
2263  */
2264 bool ewk_frame_child_add(Evas_Object* ewkFrame, WTF::PassRefPtr<WebCore::Frame> child, const WTF::String& name, const WebCore::KURL& url, const WTF::String& referrer)
2265 {
2266     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
2267     char buffer[256];
2268     Evas_Object* frame;
2269     WebCore::Frame* coreFrame;
2270
2271     frame = ewk_frame_add(smartData->base.evas);
2272     if (!frame) {
2273         ERR("Could not create ewk_frame object.");
2274         return false;
2275     }
2276
2277     coreFrame = child.get();
2278     if (coreFrame->tree())
2279         coreFrame->tree()->setName(name);
2280     else
2281         ERR("no tree for child object");
2282     smartData->frame->tree()->appendChild(child);
2283
2284     if (!ewk_frame_init(frame, smartData->view, coreFrame)) {
2285 #if ENABLE(TIZEN_REMOVE_CHILD_AFTER_FRAME_INIT_FAIL)
2286         smartData->frame->tree()->removeChild(coreFrame);
2287 #endif
2288         evas_object_del(frame);
2289         return false;
2290     }
2291     snprintf(buffer, sizeof(buffer), "EWK_Frame:child/%s", name.utf8().data());
2292     evas_object_name_set(frame, buffer);
2293     evas_object_smart_member_add(frame, ewkFrame);
2294     evas_object_show(frame);
2295
2296     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
2297     if (!coreFrame->page()) {
2298         evas_object_del(frame);
2299         return true;
2300     }
2301
2302     smartData->frame->loader()->loadURLIntoChildFrame(url, referrer, coreFrame);
2303
2304     // The frame's onload handler may have removed it from the document.
2305     // See fast/dom/null-page-show-modal-dialog-crash.html for an example.
2306     if (!coreFrame->tree()->parent()) {
2307         evas_object_del(frame);
2308         return true;
2309     }
2310
2311     // TODO: announce frame was created?
2312     return true;
2313 }
2314
2315 /**
2316  * @internal
2317  * Change the ewk view this frame is associated with.
2318  *
2319  * @param ewkFrame The ewk frame to act upon.
2320  * @param newParent The new view that will be set as the parent of the frame.
2321  */
2322 void ewk_frame_view_set(Evas_Object* ewkFrame, Evas_Object* newParent)
2323 {
2324     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2325
2326     evas_object_smart_member_del(ewkFrame);
2327     evas_object_smart_member_add(ewkFrame, newParent);
2328
2329     smartData->view = newParent;
2330 }
2331
2332 /**
2333  * @internal
2334  * Frame was destroyed by loader, remove internal reference.
2335  */
2336 void ewk_frame_core_gone(Evas_Object* ewkFrame)
2337 {
2338     DBG("ewkFrame=%p", ewkFrame);
2339     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2340     smartData->frame = 0;
2341 }
2342
2343 /**
2344  * @internal
2345  * Retrieve WebCore::Frame associated with this object.
2346  *
2347  * Avoid using this call from outside, add specific ewk_frame_*
2348  * actions instead.
2349  */
2350 WebCore::Frame* ewk_frame_core_get(const Evas_Object* ewkFrame)
2351 {
2352     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
2353     return smartData->frame;
2354 }
2355
2356
2357 /**
2358  * @internal
2359  * Reports a resource will be requested. User may override behavior of webkit by
2360  * changing values in @param request.
2361  *
2362  * @param ewkFrame Frame.
2363  * @param request Request details that user may override. Whenever values on
2364  * this struct changes, it must be properly malloc'd as it will be freed
2365  * afterwards.
2366  *
2367  * Emits signal: "resource,request,willsend"
2368  */
2369 void ewk_frame_request_will_send(Evas_Object* ewkFrame, Ewk_Frame_Resource_Request* request)
2370 {
2371     evas_object_smart_callback_call(ewkFrame, "resource,request,willsend", request);
2372 }
2373
2374 /**
2375  * @internal
2376  * Reports that there's a new resource.
2377  *
2378  * @param ewkFrame Frame.
2379  * @param request New request details. No changes are allowed to fields.
2380  *
2381  * Emits signal: "resource,request,new"
2382  */
2383 void ewk_frame_request_assign_identifier(Evas_Object* ewkFrame, const Ewk_Frame_Resource_Request* request)
2384 {
2385     evas_object_smart_callback_call(ewkFrame, "resource,request,new", (void*)request);
2386 }
2387
2388 /**
2389  * @internal
2390  * Reports that first navigation occurred
2391  *
2392  * @param ewkFrame Frame.
2393  *
2394  * Emits signal: "navigation,first"
2395  */
2396 void ewk_frame_did_perform_first_navigation(Evas_Object* ewkFrame)
2397 {
2398     evas_object_smart_callback_call(ewkFrame, "navigation,first", 0);
2399 }
2400
2401 /**
2402  * @internal
2403  * Reports frame will be saved to current state
2404  *
2405  * @param ewkFrame Frame.
2406  * @param item History item to save details to.
2407  *
2408  * Emits signal: "state,save"
2409  */
2410 void ewk_frame_view_state_save(Evas_Object* ewkFrame, WebCore::HistoryItem* item)
2411 {
2412     evas_object_smart_callback_call(ewkFrame, "state,save", 0);
2413 #if ENABLE(TIZEN_PAGE_CACHE)
2414     if(item->isInPageCache())
2415         item->setViewZoomFactor(ewk_frame_page_zoom_get(ewkFrame));
2416 #endif
2417 }
2418
2419 /**
2420  * @internal
2421  * Reports the frame started loading something.
2422  *
2423  * Emits signal: "load,started" with no parameters.
2424  */
2425 void ewk_frame_load_started(Evas_Object* ewkFrame)
2426 {
2427     Evas_Object* mainFrame;
2428     DBG("ewkFrame=%p", ewkFrame);
2429     evas_object_smart_callback_call(ewkFrame, "load,started", 0);
2430     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2431     ewk_view_load_started(smartData->view);
2432
2433     mainFrame = ewk_view_frame_main_get(smartData->view);
2434     if (mainFrame == ewkFrame)
2435         ewk_view_frame_main_load_started(smartData->view);
2436 }
2437
2438 /**
2439  * @internal
2440  * Reports the frame started provisional load.
2441  *
2442  * @param ewkFrame Frame.
2443  *
2444  * Emits signal: "load,provisional" with no parameters.
2445  */
2446 void ewk_frame_load_provisional(Evas_Object* ewkFrame)
2447 {
2448     evas_object_smart_callback_call(ewkFrame, "load,provisional", 0);
2449 }
2450
2451 /**
2452  * @internal
2453  * Reports the frame finished first layout.
2454  *
2455  * @param ewkFrame Frame.
2456  *
2457  * Emits signal: "load,firstlayout,finished" with no parameters.
2458  */
2459 void ewk_frame_load_firstlayout_finished(Evas_Object* ewkFrame)
2460 {
2461     evas_object_smart_callback_call(ewkFrame, "load,firstlayout,finished", 0);
2462 }
2463
2464 /**
2465  * @internal
2466  * Reports the frame finished first non empty layout.
2467  *
2468  * @param ewkFrame Frame.
2469  *
2470  * Emits signal: "load,nonemptylayout,finished" with no parameters.
2471  */
2472 void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object* ewkFrame)
2473 {
2474     evas_object_smart_callback_call(ewkFrame, "load,nonemptylayout,finished", 0);
2475 }
2476
2477 /**
2478  * @internal
2479  * Reports the loading of a document has finished on frame.
2480  *
2481  * @param ewkFrame Frame.
2482  *
2483  * Emits signal: "load,document,finished" with no parameters.
2484  */
2485 void ewk_frame_load_document_finished(Evas_Object* ewkFrame)
2486 {
2487     evas_object_smart_callback_call(ewkFrame, "load,document,finished", 0);
2488     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2489     ewk_view_load_document_finished(smartData->view, ewkFrame);
2490 }
2491
2492 /**
2493  * @internal
2494  * Reports load finished, optionally with error information.
2495  *
2496  * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error
2497  * if any error, or @c NULL if successful load.
2498  *
2499  * @note there should notbe any error stuff here, but trying to be
2500  *       compatible with previous WebKit.
2501  */
2502 void ewk_frame_load_finished(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
2503 {
2504     Ewk_Frame_Load_Error buffer, *error;
2505     if (!errorDomain) {
2506         DBG("ewkFrame=%p, success.", ewkFrame);
2507         error = 0;
2508     } else {
2509         DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
2510             ewkFrame, errorDomain, errorCode, isCancellation,
2511             errorDescription, failingUrl);
2512
2513         buffer.domain = errorDomain;
2514         buffer.code = errorCode;
2515         buffer.is_cancellation = isCancellation;
2516         buffer.description = errorDescription;
2517         buffer.failing_url = failingUrl;
2518         buffer.frame = ewkFrame;
2519         error = &buffer;
2520     }
2521     evas_object_smart_callback_call(ewkFrame, "load,finished", error);
2522     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2523     ewk_view_load_finished(smartData->view, error);
2524 }
2525
2526 /**
2527  * @internal
2528  * Reports load failed with error information.
2529  *
2530  * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
2531  */
2532 void ewk_frame_load_error(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
2533 {
2534     Ewk_Frame_Load_Error error;
2535
2536     DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
2537         ewkFrame, errorDomain, errorCode, isCancellation,
2538         errorDescription, failingUrl);
2539
2540     EINA_SAFETY_ON_NULL_RETURN(errorDomain);
2541
2542 #if ENABLE(TIZEN_EWK_ERROR_PAGE)
2543     char szBuffer[MAX_LOAD_ERROR_BUFFER_SIZE] = {0x00, };
2544     char szErrorType[MAX_LOAD_ERROR_TYPE_SIZE] = {0x00, };
2545     char szErrorCause[MAX_LOAD_ERROR_CAUSE_SIZE] = {0x00, };
2546     bool isChildFrame = false;
2547     char* errorUrl = 0;
2548 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
2549     bool isSSLError = false;
2550 #endif
2551     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2552
2553     // error_code == 0  is ok, error_code == -999 is request cancelled
2554     if (!errorCode || errorCode == -999)
2555         return;
2556
2557 /*
2558     // Transport Errors
2559     SOUP_STATUS_CANCELLED = 1,
2560     SOUP_STATUS_CANT_RESOLVE,
2561     SOUP_STATUS_CANT_RESOLVE_PROXY,
2562     SOUP_STATUS_CANT_CONNECT,
2563     SOUP_STATUS_CANT_CONNECT_PROXY,
2564     SOUP_STATUS_SSL_FAILED,
2565     SOUP_STATUS_IO_ERROR,
2566     SOUP_STATUS_MALFORMED,
2567     SOUP_STATUS_TRY_AGAIN,
2568 */
2569 #if ENABLE(TIZEN_INTERNATIONAL_TEXT_SUPPORT)
2570     ewk_i18n_translation_language_text_domain_set("WebKit");
2571 #endif
2572
2573     switch (errorCode) {
2574     case EWK_SOUP_STATUS_SSL_FAILED:
2575         snprintf(szErrorType, MAX_LOAD_ERROR_TYPE_SIZE, "%s (SSL Error)", WEBKITSTR_ERROR_PAGE_MESSAGE_TITLE);
2576         snprintf(szErrorCause, MAX_LOAD_ERROR_CAUSE_SIZE, "<li>%s<li>%s<li>%s", WEBKITSTR_ERROR_PAGE_SUGGESTIONS1, WEBKITSTR_ERROR_PAGE_SUGGESTIONS2, WEBKITSTR_ERROR_PAGE_SUGGESTIONS3);
2577 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
2578         isSSLError = true;
2579 #endif
2580         break;
2581     case EKW_SOUP_STATUS_CANT_RESOLVE:
2582     case EWK_SOUP_STATUS_CANT_RESOLVE_PROXY:
2583     case EWK_SOUP_STATUS_CANT_CONNECT:
2584     case EWK_SOUP_STATUS_CANT_CONNECT_PROXY:
2585         snprintf(szErrorType, MAX_LOAD_ERROR_TYPE_SIZE, "%s", WEBKITSTR_ERROR_PAGE_MESSAGE_TITLE);
2586         snprintf(szErrorCause, MAX_LOAD_ERROR_CAUSE_SIZE, "<li>%s<li>%s<li>%s", WEBKITSTR_ERROR_PAGE_SUGGESTIONS1, WEBKITSTR_ERROR_PAGE_SUGGESTIONS2, WEBKITSTR_ERROR_PAGE_SUGGESTIONS3);
2587         break;
2588     default:
2589         snprintf(szErrorType, MAX_LOAD_ERROR_TYPE_SIZE, "%s", WEBKITSTR_ERROR_PAGE_MESSAGE_TITLE_TEMP);
2590         snprintf(szErrorCause, MAX_LOAD_ERROR_CAUSE_SIZE, "<li>%s<li>%s<li>%s", WEBKITSTR_ERROR_PAGE_SUGGESTIONS1, WEBKITSTR_ERROR_PAGE_SUGGESTIONS2, WEBKITSTR_ERROR_PAGE_SUGGESTIONS3);
2591         break;
2592     }
2593 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
2594     if (isSSLError)
2595         errorUrl = (char*)smartData->uri;
2596     else
2597 #endif
2598         errorUrl = (char*)failingUrl;
2599     // check error frame has iframeTag or frameTag, if frame has these tag, it must be child frame.
2600     if (smartData->frame && smartData->frame->ownerElement())
2601         if (smartData->frame->ownerElement()->hasTagName(WebCore::HTMLNames::iframeTag) || smartData->frame->ownerElement()->hasTagName(WebCore::HTMLNames::frameTag))
2602             isChildFrame = true;
2603
2604     if (isChildFrame){
2605         snprintf(szBuffer, MAX_LOAD_ERROR_BUFFER_SIZE, ERROR_PAGE_TAG_FOR_INNER_FRAME_1"%s"ERROR_PAGE_TAG_FOR_INNER_FRAME_2"%s"ERROR_PAGE_TAG_FOR_INNER_FRAME_3, WEBKITSTR_ERROR_PAGE_TITLE, WEBKITSTR_ERROR_PAGE_SUBFRAME_MESSAGE);
2606     } else {
2607         snprintf(szBuffer, MAX_LOAD_ERROR_BUFFER_SIZE, ERROR_PAGE_TAG_1"%s"ERROR_PAGE_TAG_2"%s"ERROR_PAGE_TAG_3 "\"||%s||%s||%s\"" ERROR_PAGE_TAG_4"%s"ERROR_PAGE_TAG_5"%s"ERROR_PAGE_TAG_6"%s"ERROR_PAGE_TAG_7, WEBKITSTR_ERROR_PAGE_TITLE, szErrorType, errorUrl, WEBKITSTR_ERROR_PAGE_MESSAGE, szErrorCause, WEBKITSTR_ERROR_PAGE_MESSAGE_BEFORE_URL, WEBKITSTR_ERROR_PAGE_MESSAGE_AFTER_URL, WEBKITSTR_ERROR_PAGE_SUGGESTIONS_HEADER);
2608     }
2609
2610     ewk_frame_contents_set(ewkFrame, szBuffer, 0, 0, 0, errorUrl);
2611 #endif
2612     error.code = errorCode;
2613     error.is_cancellation = isCancellation;
2614     error.domain = errorDomain;
2615     error.description = errorDescription;
2616     error.failing_url = failingUrl;
2617     error.frame = ewkFrame;
2618     evas_object_smart_callback_call(ewkFrame, "load,error", &error);
2619 #if ENABLE(TIZEN_EWK_ERROR_PAGE)
2620     // No need to call ewk_view_load_error()
2621 #else
2622     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2623     ewk_view_load_error(smartData->view, &error);
2624 #endif
2625 }
2626
2627 /**
2628  * @internal
2629  * Reports load progress changed.
2630  *
2631  * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
2632  */
2633 void ewk_frame_load_progress_changed(Evas_Object* ewkFrame)
2634 {
2635     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2636     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
2637
2638     // TODO: this is per page, there should be a way to have per-frame.
2639     double progress = smartData->frame->page()->progress()->estimatedProgress();
2640
2641     DBG("ewkFrame=%p (p=%0.3f)", ewkFrame, progress);
2642
2643     evas_object_smart_callback_call(ewkFrame, "load,progress", &progress);
2644     ewk_view_load_progress_changed(smartData->view);
2645 }
2646
2647
2648 /**
2649  * @internal
2650  *
2651  * Reports contents size changed.
2652  */
2653 void ewk_frame_contents_size_changed(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
2654 {
2655     Evas_Coord size[2] = {width, height};
2656     evas_object_smart_callback_call(ewkFrame, "contents,size,changed", size);
2657 }
2658
2659 /**
2660  * @internal
2661  *
2662  * Reports title changed.
2663  */
2664 void ewk_frame_title_set(Evas_Object* ewkFrame, const char* title)
2665 {
2666     DBG("ewkFrame=%p, title=%s", ewkFrame, title ? title : "(null)");
2667     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2668     if (!eina_stringshare_replace(&smartData->title, title))
2669         return;
2670     evas_object_smart_callback_call(ewkFrame, "title,changed", (void*)smartData->title);
2671 }
2672
2673 /**
2674  * @internal
2675  *
2676  * Creates a view.
2677  */
2678 void ewk_frame_view_create_for_view(Evas_Object* ewkFrame, Evas_Object* view)
2679 {
2680     DBG("ewkFrame=%p, view=%p", ewkFrame, view);
2681     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2682     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
2683     Evas_Coord width, height;
2684
2685 #if !ENABLE(TIZEN_CREATE_FRAME_VIEW_ALWAYS)
2686     if (smartData->frame->view())
2687        return;
2688 #endif
2689
2690     evas_object_geometry_get(view, 0, 0, &width, &height);
2691
2692     WebCore::IntSize size(width, height);
2693     int red, green, blue, alpha;
2694     WebCore::Color background;
2695
2696     ewk_view_bg_color_get(view, &red, &green, &blue, &alpha);
2697     if (!alpha)
2698         background = WebCore::Color(0, 0, 0, 0);
2699     else if (alpha == 255)
2700         background = WebCore::Color(red, green, blue, alpha);
2701     else
2702         background = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
2703
2704     smartData->frame->createView(size, background, !alpha, WebCore::IntSize(), false);
2705     if (!smartData->frame->view())
2706         return;
2707
2708     const char* theme = ewk_view_theme_get(view);
2709     smartData->frame->view()->setEdjeTheme(theme);
2710     smartData->frame->view()->setEvasObject(ewkFrame);
2711 }
2712
2713 ssize_t ewk_frame_source_get(const Evas_Object* ewkFrame, char** frameSource)
2714 {
2715     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1);
2716     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1);
2717     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), -1);
2718     EINA_SAFETY_ON_NULL_RETURN_VAL(frameSource, -1);
2719
2720     WTF::String source;
2721     *frameSource = 0; // Saves 0 to pointer until it's not allocated.
2722
2723     if (!smartData->frame->document()->isHTMLDocument()) {
2724         // FIXME: Support others documents.
2725         WRN("Only HTML documents are supported");
2726         return -1;
2727     }
2728
2729     // Look for <html> tag. If it exists, the node contatins all document's source.
2730     WebCore::Node* documentNode = smartData->frame->document()->documentElement();
2731     if (documentNode)
2732         for (WebCore::Node* node = documentNode->firstChild(); node; node = node->parentElement()) {
2733             if (node->hasTagName(WebCore::HTMLNames::htmlTag)) {
2734                 WebCore::HTMLElement* element = static_cast<WebCore::HTMLElement*>(node);
2735                 if (element)
2736                     source = element->outerHTML();
2737                 break;
2738             }
2739         }
2740
2741     // Try to get <head> and <body> tags if <html> tag was not found.
2742     if (source.isEmpty()) {
2743         if (smartData->frame->document()->head())
2744             source = smartData->frame->document()->head()->outerHTML();
2745
2746         if (smartData->frame->document()->body())
2747             source += smartData->frame->document()->body()->outerHTML();
2748     }
2749
2750     size_t sourceLength = strlen(source.utf8().data());
2751     *frameSource = static_cast<char*>(malloc(sourceLength + 1));
2752     if (!*frameSource) {
2753         CRITICAL("Could not allocate memory.");
2754         return -1;
2755     }
2756
2757     strncpy(*frameSource, source.utf8().data(), sourceLength);
2758     (*frameSource)[sourceLength] = '\0';
2759
2760     return sourceLength;
2761 }
2762
2763 Eina_List* ewk_frame_resources_location_get(const Evas_Object* ewkFrame)
2764 {
2765     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
2766     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
2767     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), 0);
2768
2769     Eina_List* listOfImagesLocation = 0;
2770
2771     // Get src attibute of images and saves them to the Eina_List.
2772     RefPtr<WebCore::HTMLCollection> images = smartData->frame->document()->images();
2773     for (size_t index = 0; index < images->length(); ++index) {
2774         WebCore::HTMLImageElement* imageElement = static_cast<WebCore::HTMLImageElement*>(images->item(index));
2775         if (!imageElement || imageElement->src().isNull() || imageElement->src().isEmpty())
2776             continue;
2777
2778         WTF::String imageLocation = WebCore::decodeURLEscapeSequences(imageElement->src().string());
2779         // Look for duplicated location.
2780         Eina_List* listIterator = 0;
2781         void* data = 0;
2782         Eina_Bool found = false;
2783         EINA_LIST_FOREACH(listOfImagesLocation, listIterator, data)
2784             if (found = !strcmp(static_cast<char*>(data), imageLocation.utf8().data()))
2785                 break;
2786         if (found)
2787             continue;
2788
2789         char* imageLocationCopy = strdup(imageLocation.utf8().data());
2790         if (!imageLocationCopy)
2791             goto out_of_memory_handler;
2792         listOfImagesLocation = eina_list_append(listOfImagesLocation, imageLocationCopy);
2793         if (eina_error_get())
2794             goto out_of_memory_handler;
2795     }
2796     // FIXME: Get URL others resources (plugins, css, media files).
2797     return listOfImagesLocation;
2798
2799 out_of_memory_handler:
2800     CRITICAL("Could not allocate memory.");
2801     void* data;
2802     EINA_LIST_FREE(listOfImagesLocation, data)
2803         free(data);
2804     return 0;
2805 }
2806
2807 char* ewk_frame_plain_text_get(const Evas_Object* ewkFrame)
2808 {
2809     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
2810     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
2811
2812     if (!smartData->frame->document())
2813         return 0;
2814
2815     WebCore::Element* documentElement = smartData->frame->document()->documentElement();
2816
2817     if (!documentElement)
2818         return 0;
2819
2820     return strdup(documentElement->innerText().utf8().data());
2821 }
2822
2823 /**
2824  * @internal
2825  * Reports uri changed and swap internal string reference.
2826  *
2827  * Emits signal: "uri,changed" with new uri as parameter.
2828  */
2829 bool ewk_frame_uri_changed(Evas_Object* ewkFrame)
2830 {
2831     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
2832     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
2833     WTF::CString uri(smartData->frame->document()->url().string().utf8());
2834
2835     INF("uri=%s", uri.data());
2836     if (!uri.data()) {
2837         ERR("no uri");
2838         return false;
2839     }
2840
2841     eina_stringshare_replace(&smartData->uri, uri.data());
2842     evas_object_smart_callback_call(ewkFrame, "uri,changed", (void*)smartData->uri);
2843     return true;
2844 }
2845
2846 /**
2847  * @internal
2848  *
2849  * Forces layout for frame.
2850  */
2851 void ewk_frame_force_layout(Evas_Object* ewkFrame)
2852 {
2853     DBG("ewkFrame=%p", ewkFrame);
2854     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2855     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
2856     WebCore::FrameView* view = smartData->frame->view();
2857     if (view)
2858         view->forceLayout(true);
2859 }
2860
2861 #if ENABLE(TIZEN_EVAS_OBJECT_PLUGIN) && ENABLE(TIZEN_EVAS_OBJECT_PLUGIN_ORDER)
2862 struct ReorderingPluginsData {
2863     WebCore::RenderEmbeddedObject* renderObjectPlugin;
2864     WebCore::RenderEmbeddedObject* renderObjectPluginBelow;
2865     Eina_Bool renderObjectPluginAppeared;
2866 };
2867
2868 Eina_Bool _ewk_frame_traverse_layers(WebCore::RenderLayer* l, ReorderingPluginsData* reorderingPluginsData);
2869
2870 /**
2871  * Moves one plugin's canvas and clipper above, or behind other
2872  *
2873  * @param [in] renderObject which will be restacked
2874  * @param [in] referenceRenderObject relative to renderObject will be restacked
2875  * @param [in] below if true renderObject will be placed below reference, above otherwise
2876  *
2877  * @return true if successful, false otherwise
2878  */
2879 Eina_Bool _ewk_frame_move_plugin_behind_or_above_other(WebCore::RenderEmbeddedObject* renderObject, WebCore::RenderEmbeddedObject* referenceRenderObject, Eina_Bool below)
2880 {
2881     if (!renderObject || !referenceRenderObject)
2882         return false;
2883
2884     WebCore::Widget* baseWidget = renderObject->widget();
2885
2886     if (!baseWidget || !baseWidget->isPluginView())
2887         return false;
2888
2889     WebCore::PluginView* basePluginView = static_cast<WebCore::PluginView*>(baseWidget);
2890     if (!basePluginView->isPluginStarted())
2891         return false;
2892     Evas_Object* basePluginCanvas = basePluginView->getPluginCanvas();
2893     Evas_Object* basePluginClipper = basePluginView->getPluginClipper();
2894     if (!basePluginCanvas || !basePluginClipper)
2895         return false;
2896
2897     WebCore::Widget* referenceWidget = referenceRenderObject->widget();
2898     if (!referenceWidget || !referenceWidget->isPluginView())
2899         return false;
2900
2901     WebCore::PluginView* referencePluginView = static_cast<WebCore::PluginView*>(referenceWidget);
2902     if (!referencePluginView->isPluginStarted())
2903         return false;
2904     Evas_Object* referencePluginCanvas = referencePluginView->getPluginCanvas();
2905     Evas_Object* referencePluginClipper = referencePluginView->getPluginClipper();
2906     if (!referencePluginCanvas || !referencePluginClipper)
2907         return false;
2908
2909     if (below)
2910         evas_object_stack_below(basePluginCanvas, referencePluginCanvas);
2911     else
2912         evas_object_stack_above(basePluginCanvas, referencePluginClipper);
2913     evas_object_stack_above(basePluginClipper, basePluginCanvas);
2914     return true;
2915 }
2916
2917 /**
2918  * Recursively find RenderEmbeddedObject to restack
2919  */
2920 Eina_Bool _ewk_frame_find_plugin_to_reorder(WebCore::RenderObject* ewkFrame, ReorderingPluginsData* reorderingPluginsData)
2921 {
2922     if (ewkFrame->isEmbeddedObject()) {
2923         WebCore::RenderEmbeddedObject* baseRenderEmbeddedObject = static_cast<WebCore::RenderEmbeddedObject*>(ewkFrame);
2924
2925         if (ewkFrame == reorderingPluginsData->renderObjectPlugin) {
2926             reorderingPluginsData->renderObjectPluginAppeared = true;
2927         } else if (reorderingPluginsData->renderObjectPluginAppeared) { // if currently added plugin(A) was before this(B),
2928             // it means that plugin A should be moved behind B
2929             if (_ewk_frame_move_plugin_behind_or_above_other(reorderingPluginsData->renderObjectPlugin, baseRenderEmbeddedObject, true))
2930                 return true;
2931         }
2932     }
2933
2934     for (WebCore::RenderObject* child = ewkFrame->firstChild(); child; child = child->nextSibling()) {
2935         if (child->hasLayer())
2936             continue;
2937         if (_ewk_frame_find_plugin_to_reorder(child, reorderingPluginsData))
2938             return true;
2939     }
2940
2941     if (ewkFrame->isWidget()) {
2942         WebCore::Widget* widget = toRenderWidget(ewkFrame)->widget();
2943         if (widget && widget->isFrameView()) {
2944             WebCore::FrameView* view = static_cast<WebCore::FrameView*>(widget);
2945             WebCore::RenderView* root = view->frame()->contentRenderer();
2946             if (root) {
2947                 if (view->layoutPending())
2948                     view->layout();
2949                 WebCore::RenderLayer* l = root->layer();
2950                 if (l && _ewk_frame_traverse_layers(l, reorderingPluginsData))
2951                     return true;
2952             }
2953         }
2954     }
2955     return false;
2956 }
2957
2958 /**
2959  * Traverse RenderLayers recursively - negative, normal than positive z-order layers
2960  */
2961 Eina_Bool _ewk_frame_traverse_layers(WebCore::RenderLayer* l, ReorderingPluginsData* reorderingPluginsData)
2962 {
2963     // Ensure our lists are up-to-date.
2964     l->updateZOrderLists();
2965     l->updateNormalFlowList();
2966
2967     Vector<WebCore::RenderLayer*>* negList = l->negZOrderList();
2968
2969     if (negList) {
2970         for (unsigned i = 0; i != negList->size(); ++i) {
2971             if (_ewk_frame_traverse_layers(negList->at(i), reorderingPluginsData))
2972                 return true;
2973         }
2974     }
2975
2976     if (_ewk_frame_find_plugin_to_reorder(l->renderer(), reorderingPluginsData))
2977         return true;
2978
2979     if (Vector<WebCore::RenderLayer*>* normalFlowList = l->normalFlowList()) {
2980         for (unsigned i = 0; i != normalFlowList->size(); ++i) {
2981             if (_ewk_frame_traverse_layers(normalFlowList->at(i), reorderingPluginsData))
2982                 return true;
2983         }
2984     }
2985
2986     if (Vector<WebCore::RenderLayer*>* posList = l->posZOrderList()) {
2987         for (unsigned i = 0; i != posList->size(); ++i) {
2988             if (_ewk_frame_traverse_layers(posList->at(i), reorderingPluginsData))
2989                 return true;
2990         }
2991     }
2992     return false;
2993 }
2994
2995 void ewk_frame_reorder_plugin(Evas_Object* ewkFrame, WebCore::RenderEmbeddedObject* renderObject)
2996 {
2997     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2998     WebCore::Frame* frame = smartData->frame;
2999
3000     if (!frame || !renderObject)
3001         return;
3002
3003     WebCore::FrameView* frameView = frame->view();
3004     if (frameView && frameView->layoutPending())
3005         frameView->layout();
3006
3007     frame->document()->updateLayout();
3008
3009     WebCore::RenderObject* ro = frame->contentRenderer();
3010     if (!ro)
3011         return;
3012
3013     if (ro->hasLayer()) {
3014         WebCore::RenderLayer* l = toRenderBox(ro)->layer();
3015         ReorderingPluginsData reorderingPluginsData = { renderObject, 0, false };
3016         _ewk_frame_traverse_layers(l, &reorderingPluginsData);
3017     }
3018 }
3019 #endif // ENABLE(TIZEN_EVAS_OBJECT_PLUGIN) && ENABLE(TIZEN_EVAS_OBJECT_PLUGIN_ORDER)
3020
3021 /**
3022  * @internal
3023  *
3024  * Creates plugin.
3025  */
3026 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
3027 WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object *ewkFrame, 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)
3028 {
3029 #if ENABLE(TIZEN_SUPPORT_PLUGINS)
3030     DBG("ewkFrame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
3031         ewkFrame, pluginSize.width(), pluginSize.height(), element,
3032         url.string().utf8().data(), mimeType.utf8().data());
3033
3034     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3035
3036     // TODO: emit signal and ask webkit users if something else should be done.
3037     // like creating another x window (see gtk, it allows users to create
3038     // GtkPluginWidget.
3039
3040     WTF::RefPtr<WebCore::PluginView> pluginView = WebCore::PluginView::create
3041         (smartData->frame, pluginSize, element, url, paramNames, paramValues,
3042         mimeType, loadManually);
3043
3044     if (pluginView->status() == WebCore::PluginStatusLoadedSuccessfully)
3045         return pluginView;
3046 #endif
3047     return 0;
3048 }
3049 #else
3050 WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* ewkFrame, 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, Eina_Bool loadManually)
3051 {
3052     return 0;
3053 }
3054 #endif
3055
3056 /**
3057  * Obtains range selections coordinates
3058  *
3059  * @param [in] ewkFrame a frame object
3060  * @param [out] left_handle left selection side coordinates
3061  * @param [out] right_handle right selection side coordinates
3062  * @param ewkFrame Frame
3063  *
3064  * @return true if a range selection is present and false otherwise
3065  */
3066 Eina_Bool ewk_frame_selection_handlers_get(Evas_Object* ewkFrame, Eina_Rectangle* left_handle, Eina_Rectangle* right_handle)
3067 {
3068 #if ENABLE(TIZEN_TEXT_SELECTION)
3069     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3070     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3071
3072     if (!smartData->frame->selection()->isRange())
3073         return false;
3074
3075     // Is this check necessary? Leaving it for safety.
3076     WebCore::RenderView* root = smartData->frame->contentRenderer();
3077     if (!root)
3078         return false;
3079
3080     RefPtr<WebCore::Range> selectedRange = smartData->frame->selection()->toNormalizedRange();
3081
3082     Vector<WebCore::IntRect> rects;
3083     selectedRange->textRects(rects, true);
3084
3085     unsigned size = rects.size();
3086     if (size > 0) {
3087         if (left_handle)
3088             *left_handle = rects[0];
3089         if (right_handle)
3090             *right_handle = rects[size-1];
3091         // prevent from selecting zero-length selection
3092         if (left_handle && right_handle
3093             && left_handle->x == right_handle->x + right_handle->w
3094             && left_handle->y == right_handle->y)
3095             return false;
3096 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3097         if (smartData->cairoScaling) {
3098             float zoom = smartData->frame->view()->scaleFactor();
3099             if (left_handle) {
3100                 left_handle->x = float(left_handle->x) * zoom;
3101                 left_handle->y = float(left_handle->y) * zoom;
3102                 left_handle->w = float(left_handle->w) * zoom;
3103                 left_handle->h = float(left_handle->h) * zoom;
3104             }
3105             if (right_handle) {
3106                 right_handle->x = float(right_handle->x) * zoom;
3107                 right_handle->y = float(right_handle->y) * zoom;
3108                 right_handle->w = float(right_handle->w) * zoom;
3109                 right_handle->h = float(right_handle->h) * zoom;
3110             }
3111         }
3112 #endif
3113         return true;
3114     }
3115 #endif
3116     return false;
3117 }
3118
3119 /**
3120  * Selects a word at given coordinates and returns position of a selection
3121  *
3122  * @param [in] ewkFrame a frame object
3123  * @param [in] x x coordinates of a point where a word is to be selected
3124  * @param [in] y y coordinates of a point where a word is to be selected
3125  * @param [out] left_handle left selection side coordinates
3126  * @param [out] right_handle right selection side coordinates
3127  *
3128  * @return true if a selection was made and false otherwise
3129  */
3130 Eina_Bool ewk_frame_select_closest_word(Evas_Object* ewkFrame, int x, int y, Eina_Rectangle* left_handle, Eina_Rectangle* right_handle)
3131 {
3132 #if ENABLE(TIZEN_TEXT_SELECTION)
3133     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3134     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3135
3136 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3137     if (smartData->cairoScaling) {
3138         float zoom = smartData->frame->view()->scaleFactor();
3139         x = float(x) / zoom;
3140         y = float(y) / zoom;
3141     }
3142 #endif
3143
3144     WebCore::FrameSelection* fs = smartData->frame->selection();
3145
3146     WebCore::IntPoint p(x, y);
3147     WebCore::VisiblePosition position = smartData->frame->visiblePositionForPoint(p);
3148     WebCore::VisibleSelection selection(position);
3149
3150     // This changes just the 'start' and 'end' positions of the VisibleSelection
3151     selection.expandUsingGranularity(WebCore::WordGranularity);
3152     
3153     fs->setSelection(WebCore::VisibleSelection(selection.start(), selection.end()));
3154
3155     if (fs->isRange()) {
3156         // This changes just the 'start' and 'end' positions of the VisibleSelection
3157         // Find handlers positions
3158         Eina_Bool result = ewk_frame_selection_handlers_get(ewkFrame, left_handle, right_handle);
3159         if (!result) {
3160             // Sometimes there is no selected text, but isNone() returns TRUE
3161             // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
3162             // Workaround - clear the selection.
3163             // Better solution would be to modify the ewk_frame_select_closest_word()
3164             // to not select anything in the first place (for example - don't call setSelection()
3165             // if there is nothing under the cursor).
3166             fs->clear();
3167         }
3168
3169         return result;
3170     }
3171 #endif
3172     return false;
3173 }
3174
3175 Eina_Bool ewk_frame_selection_contains(Evas_Object* ewkFrame, int x, int y)
3176 {
3177 #if ENABLE(TIZEN_TEXT_SELECTION)
3178     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3179     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3180
3181 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3182     if (smartData->cairoScaling) {
3183         float zoom = smartData->frame->view()->scaleFactor();
3184         x = float(x) / zoom;
3185         y = float(y) / zoom;
3186     }
3187 #endif
3188
3189     WebCore::IntPoint p(x, y);
3190
3191     return smartData->frame->selection()->contains(p);
3192 #else
3193     LOG_ERROR("TIZEN_TEXT_SELECTION is disabled. \n");
3194     return false;
3195 #endif
3196 }
3197
3198 /**
3199  * Sets left side of a range selection
3200  *
3201  * @param [in] ewkFrame a frame object
3202  * @param [in] x x coordinates of left side of a selection
3203  * @param [in] y y coordinates of left side of a selection
3204  *
3205  * @return true if a selection was made and false otherwise
3206  */
3207 Eina_Bool ewk_frame_selection_left_set(Evas_Object* ewkFrame, int x, int y)
3208 {
3209 #if ENABLE(TIZEN_TEXT_SELECTION)
3210     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3211     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3212
3213
3214 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3215     if (smartData->cairoScaling) {
3216         float zoom = smartData->frame->view()->scaleFactor();
3217         x = float(x) / zoom;
3218         y = float(y) / zoom;
3219     }
3220 #endif
3221
3222     WebCore::FrameSelection* frameSelection = smartData->frame->selection();
3223
3224     if (!frameSelection->isRange())
3225         return false;
3226
3227     WebCore::Node* selectionEndNode = frameSelection->end().deprecatedNode();
3228     if (!selectionEndNode || !selectionEndNode->renderer())
3229         return false;
3230
3231     WebCore::IntPoint point(x, y);
3232
3233     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
3234         const int boundariesWidth = 2;
3235
3236         WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
3237         // here we cheat input field that we actually are just inside of if
3238         if (point.y() < rect.y() + boundariesWidth)
3239             point.setY(rect.y() + boundariesWidth);
3240         else if (point.y() >= rect.maxY() - boundariesWidth)
3241             point.setY(rect.maxY() - boundariesWidth - 1);
3242     }
3243
3244     WebCore::VisiblePosition* position = new WebCore::VisiblePosition(smartData->frame->visiblePositionForPoint(point));
3245     WebCore::Position extent = frameSelection->extent();
3246
3247     WebCore::Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
3248
3249     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
3250     // Check if the new position is before the extent's position
3251     if (newSelectionStartNode
3252         && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
3253         && WebCore::comparePositions(position->deepEquivalent(), extent) < 0) {
3254         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
3255         // We do it, because without this, the other modification of the selection
3256         // would destroy the 'start' and/or 'end' positions and set them to
3257         // the 'base'/'extent' positions accordingly
3258         WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
3259         frameSelection->setSelection(sel);
3260
3261         Eina_Bool oldProhibitsScrolling = smartData->frame->view()->prohibitsScrolling();
3262         smartData->frame->view()->setProhibitsScrolling(true);
3263
3264         frameSelection->setBase(*position, WebCore::UserTriggered);
3265
3266         smartData->frame->view()->setProhibitsScrolling(oldProhibitsScrolling);
3267         // This forces webkit to show selection
3268         // smartData->frame->invalidateSelection();
3269
3270         delete position;
3271         return true;
3272     }
3273     delete position;
3274 #endif
3275     return false;
3276 }
3277
3278 /**
3279  * Sets left side of a range selection
3280  *
3281  * @param [in] ewkFrame a frame object
3282  * @param [in] x x coordinates of right side of a selection
3283  * @param [in] y y coordinates of right side of a selection
3284  *
3285  * @return true if a selection was made and false otherwise
3286  */
3287 Eina_Bool ewk_frame_selection_right_set(Evas_Object* ewkFrame, int x, int y)
3288 {
3289 #if ENABLE(TIZEN_TEXT_SELECTION)
3290     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3291     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3292
3293
3294 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3295     if (smartData->cairoScaling) {
3296         float zoom = smartData->frame->view()->scaleFactor();
3297         x = float(x) / zoom;
3298         y = float(y) / zoom;
3299     }
3300 #endif
3301     WebCore::FrameSelection* frameSelection = smartData->frame->selection();
3302
3303     if (!frameSelection->isRange())
3304         return false;
3305
3306     WebCore::Node* selectionStartNode = frameSelection->start().deprecatedNode();
3307     if (!selectionStartNode || !selectionStartNode->renderer())
3308         return false;
3309
3310     WebCore::IntPoint point(x, y);
3311
3312     if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
3313         const int boundariesWidth = 2;
3314
3315         WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
3316         // here we cheat input field that we actually are just inside of if
3317         if (point.y() < rect.y() + boundariesWidth)
3318             point.setY(rect.y() + boundariesWidth);
3319         else if (point.y() >= rect.maxY() - boundariesWidth)
3320             point.setY(rect.maxY() - boundariesWidth - 1);
3321     }
3322
3323     WebCore::VisiblePosition* position = new WebCore::VisiblePosition(smartData->frame->visiblePositionForPoint(point));
3324     WebCore::Position base = frameSelection->base();
3325
3326     WebCore::Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
3327
3328     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
3329     // Check if the new position is after the base's position
3330     if (newSelectionEndNode
3331         && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
3332         && WebCore::comparePositions(position->deepEquivalent(), base) > 0) {
3333         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
3334         // We do it, because without this, the other modifications of the selection
3335         // would destroy the 'start' and/or 'end' positions and set them to
3336         // the 'base'/'extent' positions accordingly
3337         WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
3338         frameSelection->setSelection(sel);
3339
3340         Eina_Bool oldProhibitsScrolling = smartData->frame->view()->prohibitsScrolling();
3341         smartData->frame->view()->setProhibitsScrolling(true);
3342
3343         frameSelection->setExtent(*position, WebCore::UserTriggered);
3344
3345         smartData->frame->view()->setProhibitsScrolling(oldProhibitsScrolling);
3346         // This forces webkit to show selection
3347         // smartData->frame->invalidateSelection();
3348
3349         delete position;
3350         return true;
3351     }
3352     delete position;
3353 #endif
3354     return false;
3355 }
3356
3357 /**
3358 * Function clears only a range selection leaving caret selection unchanged
3359 *
3360 * @param [in] ewkFrame Frame.
3361 * @return true If selection is cleared, false if clearing selection was not possible
3362 */
3363
3364 Eina_Bool ewk_frame_selection_range_clear(Evas_Object* ewkFrame)
3365 {
3366 #if ENABLE(TIZEN_TEXT_SELECTION)
3367     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3368     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3369
3370     WebCore::FrameSelection* controller = smartData->frame->selection();
3371     if (!controller)
3372         return false;
3373
3374     if (controller->isRange()) {
3375         if (controller->isContentEditable()) {
3376             WebCore::VisiblePosition visiblePos(controller->extent());
3377             if (visiblePos.isNull())
3378                 return false;
3379             WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
3380             controller->setSelection(newSelection, WebCore::CharacterGranularity);
3381             controller->setCaretBlinkingSuspended(false);
3382         } else
3383             controller->clear();
3384         return true;
3385     }
3386     return false;
3387 #else
3388     LOG_ERROR("TIZEN_TEXT_SELECTION is disabled. \n");
3389     return false;
3390 #endif
3391 }
3392
3393 /**
3394 * Function sets caret position to given coordinates
3395 *
3396 * @param [in] ewkFrame Frame.
3397 * @param [in] x x coordinate
3398 * @param [in] y y coordinate
3399 * @return true If setting caret succeeds, false if setting caret was not possible
3400 */
3401 Eina_Bool ewk_frame_caret_position_set(Evas_Object* ewkFrame, int x, int y)
3402 {
3403 #if ENABLE(TIZEN_TEXT_CARET_HANDLING)
3404     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3405     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3406
3407     WebCore::FrameSelection* controller = smartData->frame->selection();
3408     if (!controller)
3409         return false;
3410
3411 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3412     if (smartData->cairoScaling) {
3413         float zoom = smartData->frame->view()->scaleFactor();
3414         x = float(x) / zoom;
3415         y = float(y) / zoom;
3416     }
3417 #endif
3418     WebCore::IntPoint point(x, y);
3419
3420     WebCore::HitTestResult result = smartData->frame->eventHandler()->hitTestResultAtPoint
3421             (point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
3422
3423     if (result.scrollbar())
3424         return false;
3425
3426     WebCore::Node* innerNode = result.innerNode();
3427
3428     if (!innerNode || !innerNode->renderer())
3429         return false;
3430
3431     WebCore::VisiblePosition visiblePos;
3432
3433     const int boundariesWidth = 2;
3434
3435     // we check if content is richly editable - because those input field behave other than plain text ones
3436     // sometimes they may consists a node structure and they need special approach
3437     if (innerNode->rendererIsRichlyEditable()) {
3438         // point gets inner node local coordinates
3439         point = result.localPoint();
3440         WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
3441
3442         // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
3443         // will have a better idea how to solve it
3444         // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
3445         // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
3446
3447         // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
3448         // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
3449         // node, not outside of it
3450         WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
3451
3452         if (!deepInnerNode || !deepInnerNode->renderer())
3453             return false;
3454
3455         // so we get a base node rectange
3456         WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
3457
3458         // we modify our local point to adjust it to base node local coordinates
3459         point.setX(point.x() + rect.x() - deepNodeRect.x());
3460         point.setY(point.y() + rect.y() - deepNodeRect.y());
3461
3462         // if we are outside the rect we cheat, that we are just inside of it
3463         if (point.y() < 0)
3464             point.setY(0);
3465         else if (point.y() >= deepNodeRect.height())
3466             point.setY(deepNodeRect.height() - 1);
3467
3468         // visible position created - caret ready to set
3469         visiblePos = deepInnerNode->renderer()->positionForPoint(point);
3470         if (visiblePos.isNull())
3471             return false;
3472     } else {
3473         // for plain text input fields we can get only a caret bounding box
3474         if (!controller->isCaret() || !controller->caretRenderer())
3475             return false;
3476
3477         const WebCore::Node* node = controller->start().deprecatedNode();
3478         if (!node || !node->renderer())
3479             return false;
3480
3481         WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
3482
3483         // here we also cheat input field that we actually are just inside of if
3484         if (point.x() < rect.x())
3485             point.setX(rect.x());
3486         else if (point.x() > rect.maxX())
3487             point.setX(rect.maxX());
3488         if (point.y() < rect.y() + boundariesWidth)
3489             point.setY(rect.y() + boundariesWidth);
3490         else if (point.y() >= rect.maxY() - boundariesWidth)
3491             point.setY(rect.maxY() - boundariesWidth - 1);
3492
3493         // hit test with fake (adjusted) coordinates
3494         WebCore::HitTestResult newResult = smartData->frame->eventHandler()->hitTestResultAtPoint
3495                 (point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
3496
3497         if (!newResult.isContentEditable())
3498             return false;
3499
3500         WebCore::Node* newInnerNode = newResult.innerNode();
3501
3502         if (!newInnerNode || !newInnerNode->renderer())
3503             return false;
3504
3505         // visible position created
3506         visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
3507         if (visiblePos.isNull())
3508             return false;
3509     }
3510
3511     // create visible selection from visible position
3512     WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
3513     controller->setSelection(newSelection, WebCore::CharacterGranularity);
3514     // after setting selection caret blinking is suspended by default so we are unsuspedning it
3515     controller->setCaretBlinkingSuspended(false);
3516
3517     return true;
3518 #else
3519     LOG_ERROR("TIZEN_TEXT_CARET_HANDLING is disabled. \n");
3520     return false;
3521 #endif
3522 }
3523
3524 /**
3525 * Function gets current text caret coordinates
3526 *
3527 * @param [in] ewkFrame Frame.
3528 * @param [out] x x coordinate
3529 * @param [out] y y coordinate
3530 * @param [out] width caret width
3531 * @param [out] height caret height
3532 * @return true if caret position was retrieved correctly, false if retrieving carer position was not possible
3533 */
3534 Eina_Bool ewk_frame_caret_position_get(Evas_Object* ewkFrame, int* x, int* y, int* width, int* height)
3535 {
3536 #if ENABLE(TIZEN_TEXT_CARET_HANDLING)
3537     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3538     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3539     EINA_SAFETY_ON_NULL_RETURN_VAL(x, false);
3540     EINA_SAFETY_ON_NULL_RETURN_VAL(y, false);
3541     EINA_SAFETY_ON_NULL_RETURN_VAL(width, false);
3542     EINA_SAFETY_ON_NULL_RETURN_VAL(height, false);
3543
3544     WebCore::FrameSelection* controller = smartData->frame->selection();
3545     if (!controller)
3546         return false;
3547
3548     WebCore::Node* node = controller->start().deprecatedNode();
3549     if (!node || !node->renderer() || !node->isContentEditable())
3550         return false;
3551
3552     WebCore::IntRect rect;
3553
3554     if (controller->isCaret())
3555         rect = controller->absoluteCaretBounds();
3556     else
3557         return false;
3558
3559     *x = rect.x();
3560     *y = rect.y();
3561     *width = rect.width();
3562     *height = rect.height();
3563
3564 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3565     if (smartData->cairoScaling) {
3566         float zoom = smartData->frame->view()->scaleFactor();
3567         *x = float(*x) * zoom;
3568         *y = float(*y) * zoom;
3569         *height = float(*height) * zoom;
3570         *width = float(*width) * zoom;
3571     }
3572 #endif
3573     return true;
3574 #else
3575     LOG_ERROR("TIZEN_TEXT_CARET_HANDLING is disabled. \n");
3576     return false;
3577 #endif
3578 }
3579
3580 /**
3581  * Queries if the given points are located in the same paragraph.
3582  *
3583  * @param ewkFrame frame smart object
3584  * @param x1 the horizontal postion of first point
3585  * @param y1 the vertical postion of first point
3586  * @param x2 the horizontal position of second point
3587  * @param y2 the vertical position of second point
3588  *
3589  * @return @c true if the points are located in the same paragraph, @c false if not or on failure
3590  */
3591 Eina_Bool ewk_frame_points_in_same_paragraph_get(Evas_Object* ewkFrame, int x1, int y1, int x2, int y2)
3592 {
3593 #if ENABLE(TIZEN_PARAGRAPH_SELECTION)
3594     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3595     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3596
3597 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3598     if (smartData->cairoScaling) {
3599         float zoom = smartData->frame->view()->scaleFactor();
3600         x1 = x1 / zoom;
3601         y1 = y1 / zoom;
3602         x2 = x2 / zoom;
3603         y2 = y2 / zoom;
3604     }
3605 #endif
3606
3607     WebCore::IntPoint p1(x1, y1);
3608     WebCore::IntPoint p2(x2, y2);
3609
3610     return inSameParagraph(smartData->frame->visiblePositionForPoint(p1, true), smartData->frame->visiblePositionForPoint(p2, true));
3611 #else
3612     LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3613     return false;
3614 #endif
3615 }
3616
3617 /**
3618  * Gets paragraph as a rectangle for the given point.
3619  *
3620  * @param [in] ewkFrame frame smart object
3621  * @param [in] x the horizontal postion to get paragraph
3622  * @param [in] y the vertical postion to get paragraph
3623  * @param [out] paragraph_rect the pointer to store paragraph, must @b not be @c 0
3624  *
3625  * @return @c true on success or false on failure
3626  */
3627 Eina_Bool ewk_frame_paragraph_rect_get(Evas_Object* ewkFrame, int x, int y, Eina_Rectangle* paragraph_rect)
3628 {
3629 #if ENABLE(TIZEN_PARAGRAPH_SELECTION)
3630     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3631     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3632     EINA_SAFETY_ON_NULL_RETURN_VAL(paragraph_rect, false);
3633
3634 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3635     if (smartData->cairoScaling) {
3636         float zoom = smartData->frame->view()->scaleFactor();
3637         x = x / zoom;
3638         y = y / zoom;
3639     }
3640 #endif
3641
3642     WebCore::IntPoint p(x, y);
3643
3644     WebCore::VisiblePosition position_start = startOfParagraph(smartData->frame->visiblePositionForPoint(p, true));
3645     WebCore::VisiblePosition position_end = endOfParagraph(smartData->frame->visiblePositionForPoint(p, true));
3646     paragraph_rect->x = position_start.absoluteCaretBounds().x();
3647     paragraph_rect->y = position_start.absoluteCaretBounds().y();
3648     paragraph_rect->w = position_end.absoluteCaretBounds().x() - paragraph_rect->x;
3649     paragraph_rect->h = position_end.absoluteCaretBounds().y() - paragraph_rect->y;
3650
3651 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3652     if (smartData->cairoScaling) {
3653         float zoom = smartData->frame->view()->scaleFactor();
3654         paragraph_rect->x = float(paragraph_rect->x) * zoom;
3655         paragraph_rect->y = float(paragraph_rect->y) * zoom;
3656         paragraph_rect->w = float(paragraph_rect->w) * zoom;
3657         paragraph_rect->h = float(paragraph_rect->h) * zoom;
3658     }
3659 #endif
3660     return true;
3661
3662 #else
3663     LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3664     return false;
3665 #endif
3666 }
3667
3668 Eina_Bool ewk_frame_focus_ring_invalidate(Evas_Object *ewkFrame)
3669 {
3670 #if ENABLE(TIZEN_FOCUS_RING)
3671     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3672     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3673
3674     WebCore::Node* pressNode = smartData->frame->eventHandler()->mousePressNode();
3675     if (!pressNode)
3676         return false;
3677
3678     for (WebCore::RenderObject* renderer = pressNode->renderer(); renderer; renderer = renderer->parent()) {
3679         if (renderer->style() && renderer->style()->outlineStyleIsAuto()) {
3680             renderer->style()->setOutlineStyle(WebCore::BNONE);
3681             renderer->style()->setOutlineStyleIsAuto(WebCore::AUTO_OFF);
3682             renderer->repaint(true);
3683             break;
3684         }
3685     }
3686     return true;
3687 #else
3688     return false;
3689 #endif
3690 }
3691
3692 /**
3693  * Gets paragraph selection rectangle containing already selected text
3694  *
3695  * @param [in] ewkFrame frame smart object
3696  * @param [out] paragraph_rect the pointer to store paragraph, must @b not be @c 0
3697  *
3698  * @return @c true on success or false on failure
3699  */
3700 Eina_Bool ewk_frame_paragraph_selection_rect_get(Evas_Object* ewkFrame, Eina_Rectangle* paragraph_rect)
3701 {
3702 #if ENABLE(TIZEN_PARAGRAPH_SELECTION)
3703     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3704     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
3705
3706     if (!smartData->frame->selection()->isRange())
3707         return false;
3708
3709     // Is this check necessary? Leaving it for safety.
3710     WebCore::RenderView* root = smartData->frame->contentRenderer();
3711     if (!root)
3712         return false;
3713
3714     RefPtr<WebCore::Range> selectedRange = smartData->frame->selection()->toNormalizedRange();
3715
3716     Vector<WebCore::IntRect> rects;
3717     selectedRange->textRects(rects, true);
3718     // It looks like this must be improved as WebCore is able to return different data using the same selection!
3719
3720     unsigned size = rects.size();
3721     paragraph_rect->x = rects[0].x();
3722     paragraph_rect->y = rects[0].y();
3723     int x2 = rects[0].x() + rects[0].width();
3724     int y2 = rects[0].y() + rects[0].height();
3725
3726     for (int i = 0; i < size; i++) {
3727         if (rects[i].x() < paragraph_rect->x)
3728             paragraph_rect->x = rects[i].x();
3729         if (rects[i].y() < paragraph_rect->y)
3730             paragraph_rect->y = rects[i].y();
3731         if (x2 < rects[i].x() + rects[i].width())
3732             x2 = rects[i].x() + rects[i].width();
3733         if (y2 < rects[i].y() + rects[i].height())
3734             y2 = rects[i].y() + rects[i].height();
3735      }
3736
3737      paragraph_rect->w = x2 - paragraph_rect->x;
3738      paragraph_rect->h = y2 - paragraph_rect->y;
3739
3740 #if ENABLE(TIZEN_CAIRO_SCALE_PATCH)
3741     if (smartData->cairoScaling) {
3742         float zoom = smartData->frame->view()->scaleFactor();
3743         paragraph_rect->x = float(paragraph_rect->x) * zoom;
3744         paragraph_rect->y = float(paragraph_rect->y) * zoom;
3745         paragraph_rect->w = float(paragraph_rect->w) * zoom;
3746         paragraph_rect->h = float(paragraph_rect->h) * zoom;
3747     }
3748 #endif
3749     return true;
3750 #else
3751     LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3752     return false;
3753 #endif
3754 }
3755
3756 /**
3757  * @internal
3758  * Reports submit button clicked.
3759  *
3760  * Emits signal: "submit,clicked".
3761  */
3762 void ewk_frame_submit_clicked(Evas_Object* ewkFrame, const char* username, const char* password, const char* url)
3763 {
3764 #if ENABLE(TIZEN_PASSWORD_MANAGER)
3765     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3766     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
3767
3768     const char* tab[3];
3769     tab[0] = username;
3770     tab[1] = password;
3771     tab[2] = url;
3772
3773     evas_object_smart_callback_call(ewkFrame, "submit,clicked", tab);
3774 #else
3775     LOG_ERROR("TIZEN_PASSWORD_MANAGER is disabled. \n");
3776 #endif
3777 }
3778
3779 void ewk_frame_geolocation_allowed_set(Evas_Object* ewkFrame, Eina_Bool allowed)
3780 {
3781 #if ENABLE(TIZEN_GEOLOCATION)
3782     WebCore::Frame* frame = ewk_frame_core_get(ewkFrame);
3783     if (!frame)
3784         return;
3785
3786     if (!frame->domWindow() || !frame->domWindow()->navigator())
3787         return;
3788
3789     WebCore::Geolocation* geolocation = frame->domWindow()->navigator()->geolocation();
3790     if (geolocation)
3791         geolocation->setIsAllowed(allowed);
3792 #endif
3793 }
3794
3795 #if ENABLE(TIZEN_WEBKIT_EFL_DRT)
3796 /**
3797  * Returns counter value for element
3798  *
3799  * @param ewkFrame Frame
3800  * @param element_id element id
3801  *
3802  * @return returns newly-allocated string or NULL on error
3803  */
3804 char *ewk_frame_counter_value_by_element_id_get(const Evas_Object *ewkFrame, const char *element_id)
3805 {
3806     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3807
3808     WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(element_id));
3809     if (!element)
3810         return 0;
3811
3812     return strdup(WebCore::counterValueForElement(element).utf8().data());
3813 }
3814
3815 /**
3816  * Dumps webpage's layout as a plain text
3817  *
3818  * @param ewkFrame Frame
3819  *
3820  * @return returns newly-allocated string or NULL on error
3821 */
3822 WTF::String ewk_frame_inner_text_get(const Evas_Object *ewkFrame)
3823 {
3824     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, WTF::String());
3825
3826     WebCore::FrameView *frameView = smartData->frame->view();
3827     if (frameView && frameView->layoutPending())
3828         frameView->layout();
3829
3830     WebCore::Element *documentElement = smartData->frame->document()->documentElement();
3831     if (!documentElement)
3832         return String();
3833
3834     return documentElement->innerText();
3835 }
3836
3837 /**
3838  * Dumps webpage's layout as a tree representation
3839  *
3840  * @param ewkFrame Frame
3841  *
3842  * @return returns newly-allocated string or NULL on error
3843  */
3844 char *ewk_frame_render_tree_dump_get(const Evas_Object *ewkFrame)
3845 {
3846     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3847
3848     WebCore::FrameView *frameView = smartData->frame->view();
3849     if (frameView && frameView->layoutPending())
3850         frameView->layout();
3851
3852     return strdup(WebCore::externalRepresentation(smartData->frame).utf8().data());
3853 }
3854
3855 /**
3856  * Returns child frames if exists
3857  *
3858  * @param ewkFrame Frame
3859  *
3860  * @return returns list of child frames, or @c NULL empty list. After use,
3861  * list nodes should be freed, but not the data as it is owned by WebCore.
3862  */
3863 Eina_List *ewk_frame_children_get(const Evas_Object *ewkFrame)
3864 {
3865     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3866
3867     Eina_List *childFrames = 0;
3868
3869     for (unsigned index = 0; index < smartData->frame->tree()->childCount(); index++) {
3870         WebCore::Frame *childFrame = smartData->frame->tree()->child(index);
3871         WebCore::FrameLoaderClientEfl *client = static_cast<WebCore::FrameLoaderClientEfl*>(childFrame->loader()->client());
3872         if (!client)
3873             continue;
3874         childFrames = eina_list_append(childFrames, client->webFrame());
3875     }
3876
3877     return childFrames;
3878 }
3879
3880 /**
3881  * Returns number of page element
3882  *
3883  * @param ewkFrame Frame
3884  * @param element_id element id
3885  * @param pageWidth page width
3886  * @param pageHeight page height
3887  *
3888  * @return number of page element or @c 0 on error
3889  */
3890 int ewk_frame_page_number_by_element_id_get(const Evas_Object *ewkFrame, const char *element_id, float pageWidth, float pageHeight)
3891 {
3892     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3893     WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(element_id));
3894     if (!element)
3895         return 0;
3896
3897     return WebCore::PrintContext::pageNumberForElement(element, WebCore::FloatSize(pageWidth, pageHeight));
3898 }
3899
3900 /**
3901  * Returns number of pages
3902  *
3903  * @param ewkFrame Frame
3904  * @param pageWidth page width
3905  * @param pageHeight page height
3906  *
3907  * @return returns number of pages or 0 on error
3908  */
3909 int ewk_frame_page_number_get(const Evas_Object *ewkFrame, float pageWidth, float pageHeight)
3910 {
3911     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3912
3913     return WebCore::PrintContext::numberOfPages(smartData->frame, WebCore::FloatSize(pageWidth, pageHeight));
3914 }
3915
3916 /**
3917  * Set pause on frame's animation
3918  *
3919  * @param name name
3920  * @param element_id element id
3921  * @double time time
3922  *
3923  * @return returns @c TRUE if animation was paused, @c FALSE otherwise
3924  */
3925 Eina_Bool ewk_frame_animation_pause(const Evas_Object *ewkFrame, const char *name, const char *elementId, double time)
3926 {
3927     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3928
3929     WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(elementId));
3930     if (!element || !element->renderer())
3931         return false;
3932
3933     return smartData->frame->animation()->pauseAnimationAtTime(element->renderer(), WTF::AtomicString(name), time);
3934 }
3935
3936 /**
3937  * Pause transition
3938  *
3939  * @param ewkFrame Frame
3940  * @param name
3941  * @param elementId
3942  * @param time
3943  *
3944  * @return returns @c TRUE if CSS transition was paused, @c FALSE otherwise
3945  */
3946 Eina_Bool ewk_frame_transition_pause(const Evas_Object *ewkFrame, const char *name, const char *elementId, double time)
3947 {
3948     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3949
3950     WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(elementId));
3951     if (!element || !element->renderer())
3952         return false;
3953
3954     return smartData->frame->animation()->pauseTransitionAtTime(element->renderer(), WTF::AtomicString(name), time);
3955 }
3956
3957 /**
3958  * Pause svg animation
3959  *
3960  * @param ewkFrame Frame
3961  * @param animationId
3962  * @param elementId
3963  * @param time
3964  *
3965  * @return returns @c TRUE if SVG animation was paused, @c FALSE otherwise
3966  */
3967 Eina_Bool ewk_frame_svg_animation_pause(const Evas_Object *ewkFrame, const char *animationId, const char *elementId, double time)
3968 {
3969 #if ENABLE(SVG)
3970     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3971
3972     WebCore::Document *document = smartData->frame->document();
3973     if (!document && !document->svgExtensions())
3974         return false;
3975
3976     WebCore::Element *element = document->getElementById(WTF::AtomicString(animationId));
3977     if (!element && !WebCore::SVGSMILElement::isSMILElement(element))
3978         return false;
3979
3980     return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<WebCore::SVGSMILElement*>(element), time);
3981 #else
3982     return false;
3983 #endif
3984 }
3985
3986 /**
3987  * Returns number of active animations
3988  *
3989  * @param ewkFrame Frame
3990  *
3991  * @return returns number of active animations, or @c 0 if something went wrong
3992  */
3993 unsigned ewk_frame_animation_active_number_get(const Evas_Object *ewkFrame)
3994 {
3995     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3996
3997     WebCore::AnimationController *aController = smartData->frame->animation();
3998     if (!aController)
3999         return false;
4000
4001     return aController->numberOfActiveAnimations(smartData->frame->document());
4002 }
4003
4004 /**
4005  * Suspend animations.
4006  *
4007  * @param ewkFrame Frame
4008  */
4009 void ewk_frame_animation_suspend(const Evas_Object *ewkFrame)
4010 {
4011     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
4012
4013     WebCore::AnimationController *aController = smartData->frame->animation();
4014     if (aController)
4015         aController->suspendAnimations();
4016 }
4017
4018 /**
4019  * Resume animations.
4020  *
4021  * @param ewkFrame Frame
4022  */
4023 void ewk_frame_animation_resume(const Evas_Object *ewkFrame)
4024 {
4025     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
4026
4027     WebCore::AnimationController *aController = smartData->frame->animation();
4028     if (aController)
4029         aController->resumeAnimations();
4030 }
4031
4032 /**
4033  * Gets response MIME type
4034  *
4035  * @param ewkFrame Frame
4036  *
4037  * @return returns newly-allocated string or NULL on error.
4038  */
4039 char *ewk_frame_response_mime_type_get(const Evas_Object *ewkFrame)
4040 {
4041     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
4042
4043     WebCore::DocumentLoader *docLoader = smartData->frame->loader()->documentLoader();
4044     if (!docLoader)
4045         return 0;
4046
4047     WTF::String mimeType = docLoader->responseMIMEType();
4048     if (mimeType.length() > 0)
4049         return strdup(mimeType.utf8().data());
4050
4051     return 0;
4052 }
4053
4054 /**
4055  * Clears the opener for a given frame;
4056  *
4057  * @param ewkFrame Frame
4058  */
4059 void ewk_frame_opener_clear(const Evas_Object *ewkFrame)
4060 {
4061     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
4062
4063     if (smartData->frame)
4064         smartData->frame->loader()->setOpener(0);
4065 }
4066
4067 /**
4068  * Gets the rectangle for the current selection.
4069  *
4070  * @param ewkFrame Frame
4071  * @param x Pointer to rectangle's x
4072  * @param y Pointer to rectangle's y
4073  * @param width Pointer to rectangle's width
4074  * @param width Pointer to rectangle's height
4075  * @return true if successful, false otherwise
4076  */
4077 Eina_Bool ewk_frame_selection_rectangle_get(const Evas_Object *ewkFrame, int *x, int *y, int *width, int *height)
4078 {
4079     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
4080
4081     if (!smartData->frame)
4082         return false;
4083
4084     WebCore::IntRect bounds = enclosingIntRect(smartData->frame->selection()->bounds());
4085     if (x)
4086         *x = bounds.x();
4087     if (y)
4088         *y = bounds.y();
4089     if (width)
4090         *width = bounds.width();
4091     if (height)
4092         *height = bounds.height();
4093
4094     return true;
4095 }
4096
4097 /**
4098  * @internal
4099  */
4100 unsigned int ewk_frame_pending_unload_event_count_get(const Evas_Object *ewkFrame)
4101 {
4102     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
4103
4104     return smartData->frame->domWindow()->pendingUnloadEventListeners();
4105 }
4106
4107 /**
4108  * @internal
4109  */
4110 WTF::String ewk_frame_suitable_drt_name_get(const Evas_Object *ewkFrame)
4111 {
4112     // Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm
4113     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, WTF::String());
4114
4115     const String frameName(ewk_frame_name_get(ewkFrame));
4116
4117     if (ewkFrame == ewk_view_frame_main_get(smartData->view)) {
4118         if (!frameName.isEmpty())
4119             return WTF::String("main frame \"") + frameName + WTF::String("\"");
4120
4121         return WTF::String("main frame");
4122     }
4123
4124     if (!frameName.isEmpty())
4125         return WTF::String("frame \"") + frameName + WTF::String("\"");
4126
4127     return WTF::String("frame (anonymous)");
4128 }
4129
4130 /**
4131  * @internal
4132  * Clear the name associated with the given frame.
4133  *
4134  * The name can be set by a page if it changes the window.name attribute, for example.
4135  *
4136  * @param ewkFrame The ewk frame to act upon.
4137  */
4138 void ewk_frame_name_clear(Evas_Object *ewkFrame)
4139 {
4140     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
4141     smartData->frame->tree()->clearName();
4142 }
4143
4144 #endif
4145
4146 Eina_Bool ewk_frame_zoom_text_only_get(const Evas_Object *ewkFrame)
4147 {
4148     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
4149     return smartData->textZoom;
4150 }
4151
4152 Eina_Bool ewk_frame_zoom_text_only_set(Evas_Object *ewkFrame, Eina_Bool setting)
4153 {
4154     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
4155     EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
4156     if (smartData->textZoom == setting)
4157         return true;
4158
4159     float zoom_level = smartData->textZoom ? smartData->frame->textZoomFactor() : smartData->frame->pageZoomFactor();
4160     smartData->textZoom = setting;
4161     if (smartData->textZoom)
4162         smartData->frame->setPageAndTextZoomFactors(1, zoom_level);
4163     else
4164         smartData->frame->setPageAndTextZoomFactors(zoom_level, 1);
4165     return true;
4166 }
4167
4168 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL)
4169 void ewk_frame_virtual_mouse_down_position_set(Evas_Object* ewkFrame, int x, int y)
4170 {
4171     EWK_FRAME_SD_GET(ewkFrame, smartData);
4172     EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
4173
4174 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
4175     Evas_Coord scrollX, scrollY;
4176     ewk_frame_scroll_pos_get(ewkFrame, &scrollX, &scrollY);
4177 #endif
4178     if (ewk_frame_zoom_cairo_scaling_get(ewkFrame)) {
4179         float zoom = ewk_frame_page_zoom_get(ewkFrame);
4180         x /= zoom;
4181         y /= zoom;
4182 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
4183         scrollX /= zoom;
4184         scrollY /= zoom;
4185 #endif
4186     }
4187
4188 #if ENABLE(TIZEN_SMART_FOCUSING_FOR_HIT_TEST)
4189     WebCore::CSmartFocus smartFocus(smartData->frame->view());
4190     WebCore::IntPoint smartPoint = smartFocus.getSmartTouchLocation(WebCore::IntPoint(x - scrollX, y - scrollY));
4191     // Modify the given coordinates to the smart point.
4192     x = smartPoint.x() + scrollX;
4193     y = smartPoint.y() + scrollY;
4194 #endif
4195
4196     smartData->frame->eventHandler()->setVirtualMousePressNode(WebCore::IntPoint(x, y));
4197 }
4198 #endif
4199
4200 namespace EWKPrivate {
4201
4202 WebCore::Frame *coreFrame(const Evas_Object *ewkFrame)
4203 {
4204     EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
4205     return smartData->frame;
4206 }
4207
4208 Evas_Object* kitFrame(const WebCore::Frame* coreFrame)
4209 {
4210     if (!coreFrame)
4211         return 0;
4212
4213     WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(coreFrame);
4214     if (!frameLoaderClient)
4215         return 0;
4216
4217     return frameLoaderClient->webFrame();
4218 }
4219
4220 } // namespace EWKPrivate
4221