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