2 Copyright (C) 2009-2010 ProFUSION embedded systems
3 Copyright (C) 2009-2010 Samsung Electronics
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.
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.
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.
21 // Uncomment to view frame regions and debug messages
22 // #define EWK_FRAME_DEBUG
25 #include "ewk_frame.h"
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"
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>
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>
69 #if ENABLE(TIZEN_GEOLOCATION)
70 #include "Geolocation.h"
71 #include "Navigator.h"
72 #include "NavigatorGeolocation.h"
75 #if ENABLE(TIZEN_TEXT_SELECTION)
76 #include "FrameSelection.h"
77 #include "RenderView.h"
78 #include "VisibleSelection.h"
79 #include "htmlediting.h" // for comparePositions()
82 #if ENABLE(TIZEN_PARAGRAPH_SELECTION)
83 #include "WebCore/editing/visible_units.h"
86 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
90 #if ENABLE(TIZEN_ISF_PORT)
91 #include "EditorClientEfl.h"
94 #if ENABLE(TIZEN_EVAS_OBJECT_PLUGIN)
95 #include "RenderEmbeddedObject.h"
96 #include "RenderLayer.h"
98 #if ENABLE(TIZEN_ERROR_PAGE)
99 #include "ewk_errorpage.h"
102 #if ENABLE(TIZEN_ONSCROLL_EVENT_SUPPRESSION)
103 #include "EventQueue.h"
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"
114 #if ENABLE(TIZEN_HIT_TEST)
115 #include "NamedNodeMap.h"
118 static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame";
120 struct Ewk_Frame_Smart_Data {
121 Evas_Object_Smart_Clipped_Data base;
124 #ifdef EWK_FRAME_DEBUG
127 WebCore::Frame* frame;
128 Ewk_Text_With_Direction title;
131 #if ENABLE(TIZEN_WEAK_SCROLL)
133 Eina_Bool enabled : 1;
135 Eina_Bool movingViewport : 1;
139 bool hasDisplayedMixedContent : 1;
140 bool hasRunMixedContent : 1;
143 struct Eina_Iterator_Ewk_Frame {
146 unsigned currentIndex;
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
154 #if ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
156 #ifndef EWK_TYPE_CHECK
157 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
159 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) \
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__; \
166 if (EINA_UNLIKELY(strncmp(_tmp_otype, EWK_FRAME_TYPE_STR, strlen(EWK_FRAME_TYPE_STR)))) { \
168 ("%p (%s) is not of an ewk_frame!", ewkFrame, \
169 _tmp_otype ? _tmp_otype : "(null)"); \
170 return __VA_ARGS__; \
175 #else //ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
177 #ifndef EWK_TYPE_CHECK
178 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
180 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) \
182 const char* _tmp_otype = evas_object_type_get(ewkFrame); \
183 if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) { \
185 ("%p (%s) is not of an ewk_frame!", ewkFrame, \
186 _tmp_otype ? _tmp_otype : "(null)"); \
187 return __VA_ARGS__; \
192 #endif //ENABLE(TIZEN_SMART_CLASS_TYPE_STR)
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))
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); \
201 CRITICAL("no smart data for object %p (%s)", \
202 ewkFrame, evas_object_type_get(ewkFrame)); \
203 return __VA_ARGS__; \
206 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
208 #ifdef EWK_FRAME_DEBUG
209 static inline void _ewk_frame_debug(Evas_Object* ewkFrame)
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;
215 evas_object_color_get(ewkFrame, &red, &green, &blue, &alpha);
216 evas_object_geometry_get(ewkFrame, &x, &y, &width, &height);
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);
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);
228 fprintf(stderr, "\n");
230 _ewk_frame_debug(parent);
234 static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(const WebCore::Frame* frame)
236 return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client());
239 static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* iterator, Evas_Object** data)
241 EWK_FRAME_SD_GET_OR_RETURN(iterator->object, smartData, false);
242 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
244 WebCore::FrameTree* tree = smartData->frame->tree(); // check if it's still valid
245 EINA_SAFETY_ON_NULL_RETURN_VAL(tree, false);
247 if (iterator->currentIndex < tree->childCount()) {
248 *data = EWKPrivate::kitFrame(tree->child(iterator->currentIndex++));
255 static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* iterator)
257 return iterator->object;
260 static void _ewk_frame_smart_add(Evas_Object* ewkFrame)
262 EWK_FRAME_SD_GET(ewkFrame, smartData);
265 smartData = static_cast<Ewk_Frame_Smart_Data*>(calloc(1, sizeof(Ewk_Frame_Smart_Data)));
267 CRITICAL("could not allocate Ewk_Frame_Smart_Data");
270 evas_object_smart_data_set(ewkFrame, smartData);
273 smartData->self = ewkFrame;
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);
280 #ifdef EWK_FRAME_DEBUG
281 smartData->region = evas_object_rectangle_add(smartData->base.evas);
285 evas_object_color_set(smartData->region, 128, 0, 0, 128);
288 evas_object_color_set(smartData->region, 0, 128, 0, 128);
291 evas_object_color_set(smartData->region, 0, 0, 128, 128);
294 evas_object_color_set(smartData->region, 128, 0, 0, 128);
297 evas_object_color_set(smartData->region, 128, 128, 0, 128);
300 evas_object_color_set(smartData->region, 128, 0, 128, 128);
303 evas_object_color_set(smartData->region, 0, 128, 128, 128);
312 evas_object_smart_member_add(smartData->region, ewkFrame);
313 evas_object_hide(smartData->region);
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;
324 static void _ewk_frame_smart_del(Evas_Object* ewkFrame)
326 EWK_FRAME_SD_GET(ewkFrame, smartData);
329 if (smartData->frame) {
330 WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(smartData->frame);
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;
338 eina_stringshare_del(smartData->title.string);
339 eina_stringshare_del(smartData->uri);
340 eina_stringshare_del(smartData->name);
343 _parent_sc.del(ewkFrame);
346 static void _ewk_frame_smart_resize(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
348 EWK_FRAME_SD_GET(ewkFrame, smartData);
349 evas_object_resize(smartData->base.clipper, width, height);
351 #ifdef EWK_FRAME_DEBUG
352 evas_object_resize(smartData->region, width, height);
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);
361 static void _ewk_frame_smart_set(Evas_Smart_Class* api)
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;
369 static inline Evas_Smart* _ewk_frame_smart_class_new(void)
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;
376 static Evas_Smart_Class smartClass = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR);
378 static Evas_Smart* smart = 0;
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);
389 Evas_Object* ewk_frame_view_get(const Evas_Object* ewkFrame)
391 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
392 return smartData->view;
395 Ewk_Security_Origin* ewk_frame_security_origin_get(const Evas_Object *ewkFrame)
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);
402 return ewk_security_origin_new(smartData->frame->document()->securityOrigin());
405 Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* ewkFrame)
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)));
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;
422 Evas_Object* ewk_frame_child_find(Evas_Object* ewkFrame, const char* name)
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)));
431 Eina_Bool ewk_frame_uri_set(Evas_Object* ewkFrame, const char* uri)
433 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
434 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
435 eina_stringshare_replace(&smartData->uri, uri);
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);
444 const char* ewk_frame_uri_get(const Evas_Object* ewkFrame)
446 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
447 return smartData->uri;
450 const Ewk_Text_With_Direction* ewk_frame_title_get(const Evas_Object* ewkFrame)
452 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
453 return &smartData->title;
456 const char* ewk_frame_name_get(const Evas_Object* ewkFrame)
458 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
460 if (!smartData->frame) {
461 ERR("could not get name of uninitialized frame.");
465 const WTF::String frameName = smartData->frame->tree()->uniqueName();
467 if ((smartData->name) && (smartData->name == frameName))
468 return smartData->name;
470 eina_stringshare_replace_length(&(smartData->name), frameName.utf8().data(), frameName.length());
472 return smartData->name;
475 Eina_Bool ewk_frame_contents_size_get(const Evas_Object* ewkFrame, Evas_Coord* width, Evas_Coord* height)
481 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
482 if (!smartData->frame || !smartData->frame->view())
485 *width = smartData->frame->view()->contentsWidth();
487 *height = smartData->frame->view()->contentsHeight();
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)
493 size_t length = strlen(contents);
494 if (contentsSize < 1 || contentsSize > length)
495 contentsSize = length;
497 mimeType = "text/html";
501 baseUri = "about:blank";
503 WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(baseUri));
504 WebCore::KURL unreachableKURL;
506 unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachableUri));
508 unreachableKURL = WebCore::KURL();
510 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contentsSize);
511 WebCore::SubstituteData substituteData
513 WTF::String::fromUTF8(mimeType),
514 WTF::String::fromUTF8(encoding),
515 baseKURL, unreachableKURL);
516 WebCore::ResourceRequest request(baseKURL);
518 smartData->frame->loader()->load(request, substituteData, false);
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)
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);
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)
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,
542 char* ewk_frame_script_execute(Evas_Object* ewkFrame, const char* script)
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);
548 WTF::String resultString;
549 JSC::JSValue result = smartData->frame->script()->executeScript(WTF::String::fromUTF8(script), true).jsValue();
551 if (!smartData->frame) // In case the script removed our frame from the page.
554 #if ENABLE(TIZEN_RETURN_OBJECT_RESULT_FROM_EXECUTE_SCRIPT)
557 if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
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());
567 Eina_Bool ewk_frame_editable_get(const Evas_Object* ewkFrame)
569 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
570 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
571 return smartData->editable;
574 Eina_Bool ewk_frame_editable_set(Evas_Object* ewkFrame, Eina_Bool editable)
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)
581 smartData->editable = editable;
583 smartData->frame->editor()->applyEditingStyleToBodyElement();
587 char* ewk_frame_selection_get(const Evas_Object* ewkFrame)
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())
594 return strdup(selectedText.data());
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)
600 return smartData->frame->editor()->command(WTF::String::fromUTF8(command)).execute();
605 * Unselects whatever was selected.
607 * @return @c true if operation was executed, @c false otherwise.
609 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
610 Eina_Bool ewk_frame_select_none(const Evas_Object* ewkFrame)
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");
619 * Selects everything.
621 * @return @c true if operation was executed, @c false otherwise.
623 #if ENABLE(TIZEN_SELECT_TEXT_FROM_RECTANGLE)
624 Eina_Bool ewk_frame_select_all(const Evas_Object* ewkFrame)
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");
633 * Get the copy of the selection text.
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.
641 * @return newly allocated string or @c NULL if nothing is selected or failure.
644 char* ewk_frame_select_text(const Evas_Object*ewkFrame, int x1, int y1, int x2, int y2)
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);
650 WebCore::FrameSelection* fs = smartData->frame->selection();
652 int centerX = (x2 + x1) / 2;
653 int centerY = (y2 + y1) / 2;
655 WebCore::IntPoint tmpPoint = smartData->frame->view()->contentsToWindow(WebCore::IntPoint(centerX, centerY));
656 centerX = tmpPoint.x();
657 centerY = tmpPoint.y();
659 unsigned topPadding = (y2 - y1) / 2;
660 unsigned rightPadding = (x2 - x1) / 2;
661 unsigned bottomPadding = topPadding;
662 unsigned leftPadding = rightPadding;
664 WTF::PassRefPtr<WebCore::NodeList> nodes = smartData->frame->document()->nodesFromRect(centerX , centerY , topPadding, rightPadding, bottomPadding, leftPadding, true, false);
666 WebCore::IntRect selectionRectangle(x1, y1, x2 - x1, y2 - y1);
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) {
674 WebCore::Node* tmpNode = nodes->item(i);
676 if (selectionRectangle.intersects(enclosingIntRect(tmpNode->getRect()))) {
677 lastTextNode = nodes->item(i);
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);
692 if (selectionRectangle.intersects(enclosingIntRect(tmpNode->getRect()))) {
693 firstTextNode = nodes->item(i);
702 // find visable position for [top, left] vertex inside first text node
703 WebCore::IntPoint p1(x1, y1);
705 WebCore::RenderText* firstNodeRender = (WebCore::RenderText*)firstTextNode->renderer();
706 if (!firstNodeRender)
707 EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
709 WebCore::VisiblePosition position1(firstNodeRender->positionForAbsolutePoint(p1, true));
711 // find visable position for [bottom, right] vertex inside last text node
712 WebCore::IntPoint p2(x2, y2);
714 WebCore::RenderText* lastNodeRender = (WebCore::RenderText*)lastTextNode->renderer();
716 EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
718 WebCore::VisiblePosition position2(lastNodeRender->positionForAbsolutePoint(p2, false));
720 // select all and then move selection boundaries to proper positions
721 ewk_frame_select_all(ewkFrame);
723 fs->setBase(position2, WebCore::NotUserTriggered);
724 fs->setExtent(position1, WebCore::NotUserTriggered);
726 char* text = ewk_frame_selection_get(ewkFrame);
728 ewk_frame_select_none(ewkFrame);
732 LOG_ERROR("TIZEN_SELECT_TEXT_FROM_RECTANGLE macro is disabled.\n");
738 Eina_Bool ewk_frame_text_search(const Evas_Object* ewkFrame, const char* text, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
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);
744 return smartData->frame->editor()->findString(WTF::String::fromUTF8(text), forward, caseSensitive, wrap, true);
747 unsigned int ewk_frame_text_matches_mark(Evas_Object* ewkFrame, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
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);
753 smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
754 return smartData->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), caseSensitive, limit, true);
757 Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* ewkFrame)
759 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
760 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
762 smartData->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch);
766 Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* ewkFrame, Eina_Bool highlight)
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);
774 Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* ewkFrame)
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();
782 * Comparison function used by ewk_frame_text_matches_nth_pos_get
784 static Eina_Bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& begin, const WebCore::IntRect& end)
786 return (begin.y() < end.y() || (begin.y() == end.y() && begin.x() < end.x()));
790 * Predicate used by ewk_frame_text_matches_nth_pos_get
792 static Eina_Bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& rect)
794 return (rect.x() < 0 || rect.y() < 0);
797 Eina_Bool ewk_frame_text_matches_nth_pos_get(const Evas_Object* ewkFrame, size_t number, int* x, int* y)
799 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
800 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
802 Vector<WebCore::IntRect> intRects = smartData->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch);
804 /* remove useless values */
805 std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value);
807 if (intRects.isEmpty() || number > intRects.size())
810 std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than);
813 *x = intRects[number - 1].x();
815 *y = intRects[number - 1].y();
819 Eina_Bool ewk_frame_stop(Evas_Object* ewkFrame)
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();
827 Eina_Bool ewk_frame_reload(Evas_Object* ewkFrame)
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();
835 Eina_Bool ewk_frame_reload_full(Evas_Object* ewkFrame)
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);
843 Eina_Bool ewk_frame_back(Evas_Object* ewkFrame)
845 return ewk_frame_navigate(ewkFrame, -1);
848 Eina_Bool ewk_frame_forward(Evas_Object* ewkFrame)
850 return ewk_frame_navigate(ewkFrame, 1);
853 Eina_Bool ewk_frame_load_in_progress(Evas_Object* ewkFrame)
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())
863 LOG_ERROR("TIZEN_LOADING_STATE_CHECK is disabled. \n");
868 Eina_Bool ewk_frame_navigate(Evas_Object* ewkFrame, int steps)
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))
875 page->goBackOrForward(steps);
879 Eina_Bool ewk_frame_back_possible(Evas_Object* ewkFrame)
881 return ewk_frame_navigate_possible(ewkFrame, -1);
884 Eina_Bool ewk_frame_forward_possible(Evas_Object* ewkFrame)
886 return ewk_frame_navigate_possible(ewkFrame, 1);
889 Eina_Bool ewk_frame_navigate_possible(Evas_Object* ewkFrame, int steps)
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);
897 float ewk_frame_page_zoom_get(const Evas_Object* ewkFrame)
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();
904 Eina_Bool ewk_frame_page_zoom_set(Evas_Object* ewkFrame, float pageZoomFactor)
906 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
907 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, false);
909 #if ENABLE(TIZEN_WEBCORE_SELECTIVE_RENDERING)
910 WebCore::FrameView* view = smartData->frame->view();
911 view->clearDelayedUpdateRegions();
913 smartData->frame->setPageZoomFactor(pageZoomFactor);
917 float ewk_frame_text_zoom_get(const Evas_Object* ewkFrame)
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();
924 Eina_Bool ewk_frame_text_zoom_set(Evas_Object* ewkFrame, float textZoomFactor)
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);
932 #if ENABLE(TIZEN_HIT_TEST)
933 static void _ewk_frame_hash_data_free_cb(void *data)
935 EINA_SAFETY_ON_NULL_RETURN(data);
940 void ewk_frame_hit_test_free(Ewk_Hit_Test* hitTest)
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;
957 eina_stringshare_del(hitTest->image_filename_extension);
958 eina_stringshare_del(hitTest->tag_name);
959 eina_stringshare_del(hitTest->node_value);
964 Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* ewkFrame, int x, int y)
966 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
967 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
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);
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),
979 (view->windowToContents(WebCore::IntPoint(x, y)),
981 /*allowShadowContent*/ false, /*ignoreClipping*/ true);
983 if (result.scrollbar())
985 if (!result.innerNode())
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();
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();
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();
1004 hitTest->bounding_box.x += owner->getRect().x().toInt();
1005 hitTest->bounding_box.y += owner->getRect().y().toInt();
1006 innerFrame = owner->document()->frame();
1012 hitTest->bounding_box.x = 0;
1013 hitTest->bounding_box.y = 0;
1014 hitTest->bounding_box.w = 0;
1015 hitTest->bounding_box.h = 0;
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)
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());
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());
1037 hitTest->image_uri = eina_stringshare_add(result.absoluteImageURL().string().utf8().data());
1038 hitTest->media_uri = eina_stringshare_add(result.absoluteMediaURL().string().utf8().data());
1040 int context = EWK_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
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;
1053 #if ENABLE(TIZEN_HIT_TEST)
1054 if (result.innerNonSharedNode() && result.innerNonSharedNode()->isTextNode())
1055 context |= EWK_HIT_TEST_RESULT_CONTEXT_TEXT;
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);
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;
1081 hitTest->context = static_cast<Ewk_Hit_Test_Result_Context>(context);
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;
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();
1091 namedNodeMap = result.innerNonSharedNode()->attributes();
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()));
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());
1120 WebCore::Node* hitNode = result.innerNonSharedNode();
1122 hitTest->node_value = 0;
1124 String nodeValue = hitNode->nodeValue();
1125 if (!nodeValue.isEmpty())
1126 hitTest->node_value = eina_stringshare_add(nodeValue.utf8().data());
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();
1135 if (hitNode && hitNode->isElementNode())
1136 hitElement = static_cast<WebCore::Element*>(hitNode);
1138 if (hitElement && !hitElement->tagName().isEmpty())
1139 hitTest->tag_name = eina_stringshare_add(hitElement->tagName().utf8().data());
1141 hitTest->tag_name = 0;
1148 ewk_frame_scroll_add(Evas_Object* ewkFrame, int deltaX, int deltaY)
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))
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);
1163 if (sx + deltaX < 0)
1164 // Reached left bound.
1166 else if (deltaX > fw * zoom - sx - vw * zoom)
1167 // Reached right bound.
1168 sdx = fw * zoom - sx - vw * zoom;
1172 if (sy + deltaY < 0)
1173 // Reached top bound.
1175 else if (deltaY > fh * zoom - sy - vh * zoom)
1176 // Reached bottom bound.
1177 sdy = fh * zoom - sy - vh * zoom;
1181 smartData->weakScroll.dx += sdx;
1182 smartData->weakScroll.dy += sdy;
1185 ewk_view_scroll(smartData->view, -sdx, -sdy, 0, 0, vw, vh, 0, 0, vw, vh);
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;
1199 direction = deltaY < 0 ? WebCore::ScrollUp : WebCore::ScrollDown;
1200 multiplier = deltaY < 0 ? -deltaY : deltaY;
1201 horizontalScroll = smartData->frame->eventHandler()->scrollOverflowWithMultiplier(direction, granularity, multiplier);
1204 // horizontal scroll
1206 direction = deltaX < 0 ? WebCore::ScrollLeft : WebCore::ScrollRight;
1207 multiplier = deltaX < 0 ? -deltaX : deltaX;
1208 verticalScroll = smartData->frame->eventHandler()->scrollOverflowWithMultiplier(direction, granularity, multiplier);
1211 if (verticalScroll || horizontalScroll)
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)
1225 ewk_frame_onscroll_event_generate(Evas_Object* ewkFrame)
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);
1232 smartData->frame->eventHandler()->sendScrollEvent();
1236 LOG_ERROR("TIZEN_ONSCROLL_EVENT_SUPPRESSION is disabled. \n");
1242 ewk_frame_scroll_set(Evas_Object* ewkFrame, int x, int y)
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;
1251 smartData->frame->view()->setScrollPosition(WebCore::IntPoint(x, y));
1255 Eina_Bool ewk_frame_weak_scroll_enabled_get(const Evas_Object* ewkFrame)
1257 #if ENABLE(TIZEN_WEAK_SCROLL)
1258 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1259 return smartData->weakScroll.enabled;
1265 Eina_Bool ewk_frame_weak_scroll_enabled_set(Evas_Object* ewkFrame, Eina_Bool setting)
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)
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));
1282 smartData->weakScroll.movingViewport = true;
1283 smartData->weakScroll.dx = 0;
1284 smartData->weakScroll.dy = 0;
1285 smartData->weakScroll.enabled = setting;
1293 Eina_Bool ewk_frame_weak_scroll_moving_viewport_get(Evas_Object* ewkFrame)
1295 #if ENABLE(TIZEN_WEAK_SCROLL)
1296 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1297 return smartData->weakScroll.movingViewport;
1304 ewk_frame_scroll_size_get(const Evas_Object* ewkFrame, int* width, int* height)
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();
1317 *height = point.y();
1322 ewk_frame_scroll_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
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();
1336 #if ENABLE(TIZEN_WEAK_SCROLL)
1337 if (ewk_frame_weak_scroll_enabled_get(ewkFrame))
1340 *x += smartData->weakScroll.dx;
1342 *y += smartData->weakScroll.dy;
1349 ewk_frame_scroll_scaled_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
1351 #if ENABLE(TIZEN_SCROLL_SCALED_POS_GET)
1352 if (!ewk_frame_scroll_pos_get(ewkFrame, x, y))
1355 float zoom = ewk_frame_page_zoom_get(ewkFrame);
1368 Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* ewkFrame, Eina_Bool includeScrollbars, int* x, int* y, int* width, int* height)
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);
1387 *width = rect.width();
1389 *height = rect.height();
1394 * Get the current frame visible content geometry without considering the
1395 * current scale level.
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.
1404 * @return @c true if possible, @c false otherwise and
1405 * values are zeroed.
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)
1412 Eina_Bool ewk_frame_paint_full_get(const Evas_Object* ewkFrame)
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();
1420 void ewk_frame_paint_full_set(Evas_Object* ewkFrame, Eina_Bool flag)
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);
1428 Eina_Bool ewk_frame_feed_focus_in(Evas_Object* ewkFrame)
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);
1437 Eina_Bool ewk_frame_feed_focus_out(Evas_Object* ewkFrame)
1439 // TODO: what to do on focus out?
1444 Eina_Bool ewk_frame_focused_element_geometry_get(const Evas_Object *ewkFrame, int *x, int *y, int *w, int *h)
1446 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
1447 WebCore::Document* document = smartData->frame->document();
1450 WebCore::Node* focusedNode = document->focusedNode();
1453 WebCore::IntRect nodeRect = focusedNode->getPixelSnappedRect();
1459 *w = nodeRect.width();
1461 *h = nodeRect.height();
1465 Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* ewkFrame, const Evas_Event_Mouse_Wheel* wheelEvent)
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);
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);
1476 WebCore::PlatformWheelEvent event(wheelEvent);
1477 return smartData->frame->eventHandler()->handleWheelEvent(event);
1480 Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* ewkFrame, const Evas_Event_Mouse_Down* downEvent)
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);
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);
1492 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1494 #if ENABLE(TIZEN_ISF_PORT)
1495 smartData->frame->page()->editorClient()->handleInputMethodMousePress();
1498 WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
1499 return smartData->frame->eventHandler()->handleMousePressEvent(event);
1502 Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* ewkFrame, const Evas_Event_Mouse_Up* upEvent)
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);
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);
1514 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1516 WebCore::PlatformMouseEvent event(upEvent, WebCore::IntPoint(x, y));
1518 #if ENABLE(NETSCAPE_PLUGIN_API) && ENABLE(TIZEN_SUPPORT_PLUGINS) && ENABLE(TIZEN_DONT_PAN_OVER_SOME_PLUGINS)
1520 if (WebCore::PluginView::isPluginHandlingEvents() && WebCore::PluginView::currentPluginHandlingEvents())
1521 return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1524 #if ENABLE(TIZEN_ISF_PORT)
1525 Eina_Bool result = smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1526 smartData->frame->page()->editorClient()->handleInputMethodMouseRelease();
1529 return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
1533 Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* ewkFrame, const Evas_Event_Mouse_Move* moveEvent)
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);
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);
1546 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1548 WebCore::PlatformMouseEvent event(moveEvent, WebCore::IntPoint(x, y));
1549 return smartData->frame->eventHandler()->mouseMoved(event);
1552 Eina_Bool ewk_frame_feed_touch_event(Evas_Object* ewkFrame, Ewk_Touch_Event_Type action, Eina_List* points, unsigned modifiers)
1554 #if ENABLE(TOUCH_EVENTS)
1555 EINA_SAFETY_ON_NULL_RETURN_VAL(points, false);
1556 EWK_FRAME_SD_GET(ewkFrame, smartData);
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()))
1563 if (!smartData || !smartData->frame || !ewk_view_need_touch_events_get(smartData->view))
1568 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
1570 WebCore::PlatformEvent::Type type;
1572 case EWK_TOUCH_START:
1573 type = WebCore::PlatformEvent::TouchStart;
1575 case EWK_TOUCH_MOVE:
1576 type = WebCore::PlatformEvent::TouchMove;
1579 type = WebCore::PlatformEvent::TouchEnd;
1581 case EWK_TOUCH_CANCEL:
1582 type = WebCore::PlatformEvent::TouchCancel;
1585 ASSERT_NOT_REACHED();
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;
1599 WebCore::PlatformTouchEvent touchEvent(points, WebCore::IntPoint(x, y), type, static_cast<WebCore::PlatformEvent::Modifiers>(touchModifiers));
1600 return smartData->frame->eventHandler()->handleTouchEvent(touchEvent);
1606 static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent& keyEvent)
1608 WebCore::ScrollDirection direction;
1609 WebCore::ScrollGranularity granularity;
1611 int keyCode = keyEvent.windowsVirtualKeyCode();
1615 granularity = WebCore::ScrollByPage;
1616 if (keyEvent.shiftKey())
1617 direction = WebCore::ScrollUp;
1619 direction = WebCore::ScrollDown;
1622 granularity = WebCore::ScrollByPage;
1623 direction = WebCore::ScrollDown;
1626 granularity = WebCore::ScrollByPage;
1627 direction = WebCore::ScrollUp;
1630 granularity = WebCore::ScrollByDocument;
1631 direction = WebCore::ScrollUp;
1634 granularity = WebCore::ScrollByDocument;
1635 direction = WebCore::ScrollDown;
1638 granularity = WebCore::ScrollByLine;
1639 direction = WebCore::ScrollLeft;
1642 granularity = WebCore::ScrollByLine;
1643 direction = WebCore::ScrollRight;
1646 direction = WebCore::ScrollUp;
1647 if (keyEvent.ctrlKey())
1648 granularity = WebCore::ScrollByDocument;
1650 granularity = WebCore::ScrollByLine;
1653 direction = WebCore::ScrollDown;
1654 if (keyEvent.ctrlKey())
1655 granularity = WebCore::ScrollByDocument;
1657 granularity = WebCore::ScrollByLine;
1663 if (frame->eventHandler()->scrollOverflow(direction, granularity))
1666 frame->view()->scroll(direction, granularity);
1670 Eina_Bool ewk_frame_feed_key_down(Evas_Object* ewkFrame, const Evas_Event_Key_Down* downEvent)
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);
1676 DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1677 ewkFrame, downEvent->keyname, downEvent->key ? downEvent->key : "", downEvent->string ? downEvent->string : "");
1679 WebCore::PlatformKeyboardEvent event(downEvent);
1680 if (smartData->frame->eventHandler()->keyEvent(event))
1683 return _ewk_frame_handle_key_scrolling(smartData->frame, event);
1686 Eina_Bool ewk_frame_feed_key_up(Evas_Object* ewkFrame, const Evas_Event_Key_Up* upEvent)
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);
1692 DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1693 ewkFrame, upEvent->keyname, upEvent->key ? upEvent->key : "", upEvent->string ? upEvent->string : "");
1695 WebCore::PlatformKeyboardEvent event(upEvent);
1696 return smartData->frame->eventHandler()->keyEvent(event);
1699 Ewk_Text_Selection_Type ewk_frame_text_selection_type_get(const Evas_Object* ewkFrame)
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);
1704 WebCore::FrameSelection* controller = smartData->frame->selection();
1706 return EWK_TEXT_SELECTION_NONE;
1708 return static_cast<Ewk_Text_Selection_Type>(controller->selectionType());
1711 /* internal methods ****************************************************/
1715 * Reports that editor client selection was changed.
1717 * Emits signal: "editorclient,selection,changed" with no parameters.
1718 * @param ewkFrame Frame
1720 * Emits signal: "editorclientselection,changed" with no parameters.
1722 void ewk_frame_editor_client_selection_changed(Evas_Object* ewkFrame)
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);
1731 * Reports that editor client's contents were changed.
1733 * @param ewkFrame Frame
1735 * Emits signal: "editorclient,contents,changed" with no parameters.
1737 void ewk_frame_editor_client_contents_changed(Evas_Object* ewkFrame)
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);
1747 * Creates a new EFL WebKit Frame object.
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
1753 * @param canvas canvas where to create the frame object
1755 * @return a new frame object or @c 0 on failure
1757 Evas_Object* ewk_frame_add(Evas* canvas)
1759 return evas_object_smart_add(canvas, _ewk_frame_smart_class_new());
1765 * Initialize frame based on actual WebKit frame.
1767 * This is internal and should never be called by external users.
1769 bool ewk_frame_init(Evas_Object* ewkFrame, Evas_Object* view, WebCore::Frame* frame)
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;
1781 ERR("frame %p already set for %p, ignored new %p",
1782 smartData->frame, ewkFrame, frame);
1789 * Adds child to the frame.
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)
1793 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1796 WebCore::Frame* coreFrame;
1798 frame = ewk_frame_add(smartData->base.evas);
1800 ERR("Could not create ewk_frame object.");
1804 coreFrame = child.get();
1805 if (coreFrame->tree())
1806 coreFrame->tree()->setName(name);
1808 ERR("no tree for child object");
1809 smartData->frame->tree()->appendChild(child);
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);
1815 evas_object_del(frame);
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);
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);
1829 evas_object_smart_callback_call(smartData->view, "frame,created", frame);
1830 smartData->frame->loader()->loadURLIntoChildFrame(url, referrer, coreFrame);
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);
1839 // TODO: announce frame was created?
1845 * Change the ewk view this frame is associated with.
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.
1850 void ewk_frame_view_set(Evas_Object* ewkFrame, Evas_Object* newParent)
1852 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1854 evas_object_smart_member_del(ewkFrame);
1855 evas_object_smart_member_add(ewkFrame, newParent);
1857 smartData->view = newParent;
1862 * Frame was destroyed by loader, remove internal reference.
1864 void ewk_frame_core_gone(Evas_Object* ewkFrame)
1866 DBG("ewkFrame=%p", ewkFrame);
1867 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1868 smartData->frame = 0;
1873 * Retrieve WebCore::Frame associated with this object.
1875 * Avoid using this call from outside, add specific ewk_frame_*
1878 WebCore::Frame* ewk_frame_core_get(const Evas_Object* ewkFrame)
1880 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1881 return smartData->frame;
1886 * Reports cancellation of a client redirect.
1888 * @param ewkFrame Frame.
1890 * Emits signal: "redirect,cancelled"
1892 void ewk_frame_redirect_cancelled(Evas_Object* ewkFrame)
1894 evas_object_smart_callback_call(ewkFrame, "redirect,cancelled", 0);
1899 * Reports receipt of server redirect for provisional load.
1901 * @param ewkFrame Frame.
1903 * Emits signal: "redirect,load,provisional"
1905 void ewk_frame_redirect_provisional_load(Evas_Object* ewkFrame)
1907 evas_object_smart_callback_call(ewkFrame, "redirect,load,provisional", 0);
1912 * Reports that a client redirect will be performed.
1914 * @param ewkFrame Frame.
1915 * @param url Redirection URL.
1917 * Emits signal: "redirect,requested"
1919 void ewk_frame_redirect_requested(Evas_Object* ewkFrame, const char* url)
1921 evas_object_smart_callback_call(ewkFrame, "redirect,requested", (void*)url);
1926 * Reports a resource will be requested. User may override behavior of webkit by
1927 * changing values in @param request.
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.
1934 * Emits signal: "resource,request,willsend"
1936 void ewk_frame_request_will_send(Evas_Object* ewkFrame, Ewk_Frame_Resource_Messages* messages)
1938 evas_object_smart_callback_call(ewkFrame, "resource,request,willsend", messages);
1943 * Reports that there's a new resource.
1945 * @param ewkFrame Frame.
1946 * @param request New request details. No changes are allowed to fields.
1948 * Emits signal: "resource,request,new"
1950 void ewk_frame_request_assign_identifier(Evas_Object* ewkFrame, const Ewk_Frame_Resource_Request* request)
1952 evas_object_smart_callback_call(ewkFrame, "resource,request,new", (void*)request);
1957 * Reports that a response to a resource request was received.
1959 * @param ewkFrame Frame.
1960 * @param request Response details. No changes are allowed to fields.
1962 * Emits signal: "resource,response,received"
1964 void ewk_frame_response_received(Evas_Object* ewkFrame, Ewk_Frame_Resource_Response* response)
1966 evas_object_smart_callback_call(ewkFrame, "resource,response,received", response);
1971 * Reports that first navigation occurred
1973 * @param ewkFrame Frame.
1975 * Emits signal: "navigation,first"
1977 void ewk_frame_did_perform_first_navigation(Evas_Object* ewkFrame)
1979 evas_object_smart_callback_call(ewkFrame, "navigation,first", 0);
1984 * Reports frame will be saved to current state
1986 * @param ewkFrame Frame.
1987 * @param item History item to save details to.
1989 * Emits signal: "state,save"
1991 void ewk_frame_view_state_save(Evas_Object* ewkFrame, WebCore::HistoryItem* item)
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));
2002 * Reports the frame committed load.
2004 * Emits signal: "load,committed" with no parameters.
2006 void ewk_frame_load_committed(Evas_Object* ewkFrame)
2008 evas_object_smart_callback_call(ewkFrame, "load,committed", 0);
2013 * Reports the frame started loading something.
2015 * Emits signal: "load,started" with no parameters.
2017 void ewk_frame_load_started(Evas_Object* ewkFrame)
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);
2025 mainFrame = ewk_view_frame_main_get(smartData->view);
2026 if (mainFrame == ewkFrame)
2027 ewk_view_frame_main_load_started(smartData->view);
2032 * Reports the frame started provisional load.
2034 * @param ewkFrame Frame.
2036 * Emits signal: "load,provisional" with no parameters.
2038 void ewk_frame_load_provisional(Evas_Object* ewkFrame)
2040 evas_object_smart_callback_call(ewkFrame, "load,provisional", 0);
2045 * Reports the frame provisional load failed.
2047 * @param ewkFrame Frame.
2048 * @param error Load error.
2050 * Emits signal: "load,provisional,failed" with pointer to Ewk_Frame_Load_Error.
2052 void ewk_frame_load_provisional_failed(Evas_Object* ewkFrame, const Ewk_Frame_Load_Error* error)
2054 evas_object_smart_callback_call(ewkFrame, "load,provisional,failed", const_cast<Ewk_Frame_Load_Error*>(error));
2059 * Reports the frame finished first layout.
2061 * @param ewkFrame Frame.
2063 * Emits signal: "load,firstlayout,finished" with no parameters.
2065 void ewk_frame_load_firstlayout_finished(Evas_Object* ewkFrame)
2067 evas_object_smart_callback_call(ewkFrame, "load,firstlayout,finished", 0);
2072 * Reports the frame finished first non empty layout.
2074 * @param ewkFrame Frame.
2076 * Emits signal: "load,nonemptylayout,finished" with no parameters.
2078 void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object* ewkFrame)
2080 evas_object_smart_callback_call(ewkFrame, "load,nonemptylayout,finished", 0);
2085 * Reports the loading of a document has finished on frame.
2087 * @param ewkFrame Frame.
2089 * Emits signal: "load,document,finished" with no parameters.
2091 void ewk_frame_load_document_finished(Evas_Object* ewkFrame)
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);
2100 * Reports load finished, optionally with error information.
2102 * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error
2103 * if any error, or @c NULL if successful load.
2105 * @note there should notbe any error stuff here, but trying to be
2106 * compatible with previous WebKit.
2108 void ewk_frame_load_finished(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
2110 Ewk_Frame_Load_Error buffer, *error;
2112 DBG("ewkFrame=%p, success.", ewkFrame);
2115 DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
2116 ewkFrame, errorDomain, errorCode, isCancellation,
2117 errorDescription, failingUrl);
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;
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);
2135 * Reports resource load finished.
2137 * Emits signal: "load,resource,finished" with the resource
2138 * request identifier.
2140 void ewk_frame_load_resource_finished(Evas_Object* ewkFrame, unsigned long identifier)
2142 evas_object_smart_callback_call(ewkFrame, "load,resource,finished", &identifier);
2147 * Reports resource load failure, with error information.
2149 * Emits signal: "load,resource,failed" with the error information.
2151 void ewk_frame_load_resource_failed(Evas_Object* ewkFrame, Ewk_Frame_Load_Error* error)
2153 evas_object_smart_callback_call(ewkFrame, "load,resource,failed", error);
2158 * Reports load failed with error information.
2160 * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
2162 void ewk_frame_load_error(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, bool isCancellation, const char* errorDescription, const char* failingUrl)
2164 Ewk_Frame_Load_Error error;
2166 DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
2167 ewkFrame, errorDomain, errorCode, isCancellation,
2168 errorDescription, failingUrl);
2170 EINA_SAFETY_ON_NULL_RETURN(errorDomain);
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;
2178 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
2179 bool isSSLError = false;
2181 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2183 // error_code == 0 is ok, error_code == -999 is request cancelled
2184 if (!errorCode || errorCode == -999)
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,
2199 #if ENABLE(TIZEN_INTERNATIONAL_TEXT_SUPPORT)
2200 ewk_i18n_translation_language_text_domain_set("WebKit");
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)
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);
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);
2223 #if ENABLE(TIZEN_CERTIFICATE_HANDLING)
2225 errorUrl = (char*)smartData->uri;
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;
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);
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);
2240 ewk_frame_contents_set(ewkFrame, szBuffer, 0, 0, 0, errorUrl);
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()
2253 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2254 ewk_view_load_error(smartData->view, &error);
2260 * Reports load progress changed.
2262 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
2264 void ewk_frame_load_progress_changed(Evas_Object* ewkFrame)
2266 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2267 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
2269 // TODO: this is per page, there should be a way to have per-frame.
2270 double progress = smartData->frame->page()->progress()->estimatedProgress();
2272 DBG("ewkFrame=%p (p=%0.3f)", ewkFrame, progress);
2274 evas_object_smart_callback_call(ewkFrame, "load,progress", &progress);
2275 ewk_view_load_progress_changed(smartData->view);
2280 * Reports new intent.
2282 * Emits signal: "intent,new" with pointer to a Ewk_Intent_Request.
2284 void ewk_frame_intent_new(Evas_Object* ewkFrame, Ewk_Intent_Request* request)
2286 #if ENABLE(WEB_INTENTS)
2287 evas_object_smart_callback_call(ewkFrame, "intent,new", request);
2294 * Reports contents size changed.
2296 void ewk_frame_contents_size_changed(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
2298 Evas_Coord size[2] = {width, height};
2299 evas_object_smart_callback_call(ewkFrame, "contents,size,changed", size);
2305 * Reports title changed.
2307 void ewk_frame_title_set(Evas_Object* ewkFrame, const Ewk_Text_With_Direction* title)
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))
2313 smartData->title.direction = title->direction;
2314 evas_object_smart_callback_call(ewkFrame, "title,changed", (void*)title);
2322 void ewk_frame_view_create_for_view(Evas_Object* ewkFrame, Evas_Object* view)
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;
2329 #if !ENABLE(TIZEN_CREATE_FRAME_VIEW_ALWAYS)
2330 if (smartData->frame->view())
2334 evas_object_geometry_get(view, 0, 0, &width, &height);
2336 WebCore::IntSize size(width, height);
2337 int red, green, blue, alpha;
2338 WebCore::Color background;
2340 ewk_view_bg_color_get(view, &red, &green, &blue, &alpha);
2342 background = WebCore::Color(0, 0, 0, 0);
2343 else if (alpha == 255)
2344 background = WebCore::Color(red, green, blue, alpha);
2346 background = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
2348 smartData->frame->createView(size, background, !alpha, WebCore::IntSize(), false);
2349 if (!smartData->frame->view())
2352 const char* theme = ewk_view_theme_get(view);
2353 smartData->frame->view()->setEdjeTheme(theme);
2354 smartData->frame->view()->setEvasObject(ewkFrame);
2356 ewk_frame_mixed_content_displayed_set(ewkFrame, false);
2357 ewk_frame_mixed_content_run_set(ewkFrame, false);
2360 ssize_t ewk_frame_source_get(const Evas_Object* ewkFrame, char** frameSource)
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);
2368 *frameSource = 0; // Saves 0 to pointer until it's not allocated.
2370 if (!smartData->frame->document()->isHTMLDocument()) {
2371 // FIXME: Support others documents.
2372 WRN("Only HTML documents are supported");
2376 // Look for <html> tag. If it exists, the node contatins all document's source.
2377 WebCore::Node* documentNode = smartData->frame->document()->documentElement();
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);
2383 source = element->outerHTML();
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();
2393 if (smartData->frame->document()->body())
2394 source += smartData->frame->document()->body()->outerHTML();
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.");
2404 strncpy(*frameSource, source.utf8().data(), sourceLength);
2405 (*frameSource)[sourceLength] = '\0';
2407 return sourceLength;
2410 Eina_List* ewk_frame_resources_location_get(const Evas_Object* ewkFrame)
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);
2416 Eina_List* listOfImagesLocation = 0;
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())
2425 WTF::String imageLocation = WebCore::decodeURLEscapeSequences(imageElement->src().string());
2426 // Look for duplicated location.
2427 Eina_List* listIterator = 0;
2429 Eina_Bool found = false;
2430 EINA_LIST_FOREACH(listOfImagesLocation, listIterator, data)
2431 if (found = !strcmp(static_cast<char*>(data), imageLocation.utf8().data()))
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;
2443 // FIXME: Get URL others resources (plugins, css, media files).
2444 return listOfImagesLocation;
2446 out_of_memory_handler:
2447 CRITICAL("Could not allocate memory.");
2449 EINA_LIST_FREE(listOfImagesLocation, data)
2454 char* ewk_frame_plain_text_get(const Evas_Object* ewkFrame)
2456 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
2457 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
2459 if (!smartData->frame->document())
2462 WebCore::Element* documentElement = smartData->frame->document()->documentElement();
2464 if (!documentElement)
2467 return strdup(documentElement->innerText().utf8().data());
2470 Eina_Bool ewk_frame_mixed_content_displayed_get(const Evas_Object* ewkFrame)
2472 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
2473 return smartData->hasDisplayedMixedContent;
2476 Eina_Bool ewk_frame_mixed_content_run_get(const Evas_Object* ewkFrame)
2478 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
2479 return smartData->hasRunMixedContent;
2482 Ewk_Certificate_Status ewk_frame_certificate_status_get(Evas_Object* ewkFrame)
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);
2487 const WebCore::FrameLoader* frameLoader = smartData->frame->loader();
2488 const WebCore::DocumentLoader* documentLoader = frameLoader->documentLoader();
2489 const WebCore::KURL documentURL = documentLoader->requestURL();
2491 if (!documentURL.protocolIs("https"))
2492 return EWK_CERTIFICATE_STATUS_NO_CERTIFICATE;
2494 if (frameLoader->subframeIsLoading())
2495 return EWK_CERTIFICATE_STATUS_NO_CERTIFICATE;
2497 SoupMessage* soupMessage = documentLoader->request().toSoupMessage();
2499 if (soupMessage && (soup_message_get_flags(soupMessage) & SOUP_MESSAGE_CERTIFICATE_TRUSTED))
2500 return EWK_CERTIFICATE_STATUS_TRUSTED;
2502 return EWK_CERTIFICATE_STATUS_UNTRUSTED;
2507 * Reports frame favicon changed.
2509 * @param ewkFrame Frame.
2511 * Emits signal: "icon,changed" with no parameters.
2513 void ewk_frame_icon_changed(Evas_Object* ewkFrame)
2515 DBG("ewkFrame=%p", ewkFrame);
2516 evas_object_smart_callback_call(ewkFrame, "icon,changed", 0);
2521 * Reports uri changed and swap internal string reference.
2523 * Emits signal: "uri,changed" with new uri as parameter.
2525 bool ewk_frame_uri_changed(Evas_Object* ewkFrame)
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());
2531 INF("uri=%s", uri.data());
2537 eina_stringshare_replace(&smartData->uri, uri.data());
2538 evas_object_smart_callback_call(ewkFrame, "uri,changed", (void*)smartData->uri);
2545 * Forces layout for frame.
2547 void ewk_frame_force_layout(Evas_Object* ewkFrame)
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();
2554 view->forceLayout(true);
2557 #if ENABLE(TIZEN_EVAS_OBJECT_PLUGIN)
2558 struct ReorderingPluginsData {
2559 WebCore::RenderEmbeddedObject* renderObjectPlugin;
2560 WebCore::RenderEmbeddedObject* renderObjectPluginBelow;
2561 Eina_Bool renderObjectPluginAppeared;
2564 Eina_Bool _ewk_frame_traverse_layers(WebCore::RenderLayer* l, ReorderingPluginsData* reorderingPluginsData);
2567 * Moves one plugin's canvas and clipper above, or behind other
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
2573 * @return true if successful, false otherwise
2575 Eina_Bool _ewk_frame_move_plugin_behind_or_above_other(WebCore::RenderEmbeddedObject* renderObject, WebCore::RenderEmbeddedObject* referenceRenderObject, Eina_Bool below)
2577 if (!renderObject || !referenceRenderObject)
2580 WebCore::Widget* baseWidget = renderObject->widget();
2582 if (!baseWidget || !baseWidget->isPluginView())
2585 WebCore::PluginView* basePluginView = static_cast<WebCore::PluginView*>(baseWidget);
2586 if (!basePluginView->isPluginStarted())
2588 Evas_Object* basePluginCanvas = basePluginView->getPluginCanvas();
2589 Evas_Object* basePluginClipper = basePluginView->getPluginClipper();
2590 if (!basePluginCanvas || !basePluginClipper)
2593 WebCore::Widget* referenceWidget = referenceRenderObject->widget();
2594 if (!referenceWidget || !referenceWidget->isPluginView())
2597 WebCore::PluginView* referencePluginView = static_cast<WebCore::PluginView*>(referenceWidget);
2598 if (!referencePluginView->isPluginStarted())
2600 Evas_Object* referencePluginCanvas = referencePluginView->getPluginCanvas();
2601 Evas_Object* referencePluginClipper = referencePluginView->getPluginClipper();
2602 if (!referencePluginCanvas || !referencePluginClipper)
2606 evas_object_stack_below(basePluginCanvas, referencePluginCanvas);
2608 evas_object_stack_above(basePluginCanvas, referencePluginClipper);
2609 evas_object_stack_above(basePluginClipper, basePluginCanvas);
2614 * Recursively find RenderEmbeddedObject to restack
2616 Eina_Bool _ewk_frame_find_plugin_to_reorder(WebCore::RenderObject* ewkFrame, ReorderingPluginsData* reorderingPluginsData)
2618 if (ewkFrame->isEmbeddedObject()) {
2619 WebCore::RenderEmbeddedObject* baseRenderEmbeddedObject = static_cast<WebCore::RenderEmbeddedObject*>(ewkFrame);
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))
2630 for (WebCore::RenderObject* child = ewkFrame->firstChild(); child; child = child->nextSibling()) {
2631 if (child->hasLayer())
2633 if (_ewk_frame_find_plugin_to_reorder(child, reorderingPluginsData))
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();
2643 if (view->layoutPending())
2645 WebCore::RenderLayer* l = root->layer();
2646 if (l && _ewk_frame_traverse_layers(l, reorderingPluginsData))
2655 * Traverse RenderLayers recursively - negative, normal than positive z-order layers
2657 Eina_Bool _ewk_frame_traverse_layers(WebCore::RenderLayer* l, ReorderingPluginsData* reorderingPluginsData)
2659 // Ensure our lists are up-to-date.
2660 l->updateLayerListsIfNeeded();
2662 Vector<WebCore::RenderLayer*>* negList = l->negZOrderList();
2665 for (unsigned i = 0; i != negList->size(); ++i) {
2666 if (_ewk_frame_traverse_layers(negList->at(i), reorderingPluginsData))
2671 if (_ewk_frame_find_plugin_to_reorder(l->renderer(), reorderingPluginsData))
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))
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))
2690 void ewk_frame_reorder_plugin(Evas_Object* ewkFrame, WebCore::RenderEmbeddedObject* renderObject)
2692 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
2693 WebCore::Frame* frame = smartData->frame;
2695 if (!frame || !renderObject)
2698 WebCore::FrameView* frameView = frame->view();
2699 if (frameView && frameView->layoutPending())
2700 frameView->layout();
2702 frame->document()->updateLayout();
2704 WebCore::RenderObject* ro = frame->contentRenderer();
2708 if (ro->hasLayer()) {
2709 WebCore::RenderLayer* l = toRenderBox(ro)->layer();
2710 ReorderingPluginsData reorderingPluginsData = { renderObject, 0, false };
2711 _ewk_frame_traverse_layers(l, &reorderingPluginsData);
2714 #endif // ENABLE(TIZEN_EVAS_OBJECT_PLUGIN)
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)
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());
2728 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, 0);
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
2734 WTF::RefPtr<WebCore::PluginView> pluginView = WebCore::PluginView::create
2735 (sd->frame, pluginSize, element, url, paramNames, paramValues,
2736 mimeType, loadManually);
2738 if (pluginView->status() == WebCore::PluginStatusLoadedSuccessfully)
2739 return pluginView.release();
2740 #endif // #if ENABLE(NETSCAPE_PLUGIN_API)
2745 * Obtains range selections coordinates
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
2752 * @return true if a range selection is present and false otherwise
2754 Eina_Bool ewk_frame_selection_handlers_get(Evas_Object* ewkFrame, Eina_Rectangle* left_handle, Eina_Rectangle* right_handle)
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);
2760 if (!smartData->frame->selection()->isRange())
2763 // Is this check necessary? Leaving it for safety.
2764 WebCore::RenderView* root = smartData->frame->contentRenderer();
2768 RefPtr<WebCore::Range> selectedRange = smartData->frame->selection()->toNormalizedRange();
2770 Vector<WebCore::IntRect> rects;
2771 selectedRange->textRects(rects, true);
2773 unsigned size = rects.size();
2776 *left_handle = rects[0];
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)
2791 * Selects a word at given coordinates and returns position of a selection
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
2799 * @return true if a selection was made and false otherwise
2801 Eina_Bool ewk_frame_select_closest_word(Evas_Object* ewkFrame, int x, int y, Eina_Rectangle* left_handle, Eina_Rectangle* right_handle)
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);
2807 WebCore::FrameSelection* fs = smartData->frame->selection();
2809 WebCore::IntPoint p(x, y);
2810 WebCore::VisiblePosition position = smartData->frame->visiblePositionForPoint(p);
2811 WebCore::VisibleSelection selection(position);
2813 // This changes just the 'start' and 'end' positions of the VisibleSelection
2814 selection.expandUsingGranularity(WebCore::WordGranularity);
2816 fs->setSelection(WebCore::VisibleSelection(selection.start(), selection.end()));
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);
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).
2838 Eina_Bool ewk_frame_selection_contains(Evas_Object* ewkFrame, int x, int y)
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);
2844 WebCore::IntPoint p(x, y);
2846 return smartData->frame->selection()->contains(p);
2848 LOG_ERROR("TIZEN_TEXT_SELECTION is disabled. \n");
2854 * Sets left side of a range selection
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
2860 * @return true if a selection was made and false otherwise
2862 Eina_Bool ewk_frame_selection_left_set(Evas_Object* ewkFrame, int x, int y)
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);
2869 WebCore::FrameSelection* frameSelection = smartData->frame->selection();
2871 if (!frameSelection->isRange())
2874 WebCore::Node* selectionEndNode = frameSelection->end().deprecatedNode();
2875 if (!selectionEndNode || !selectionEndNode->renderer())
2878 WebCore::IntPoint point(x, y);
2880 if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
2881 const int boundariesWidth = 2;
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);
2891 WebCore::VisiblePosition* position = new WebCore::VisiblePosition(smartData->frame->visiblePositionForPoint(point));
2892 WebCore::Position extent = frameSelection->extent();
2894 WebCore::Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
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);
2908 Eina_Bool oldProhibitsScrolling = smartData->frame->view()->prohibitsScrolling();
2909 smartData->frame->view()->setProhibitsScrolling(true);
2911 frameSelection->setBase(*position, WebCore::UserTriggered);
2913 smartData->frame->view()->setProhibitsScrolling(oldProhibitsScrolling);
2914 // This forces webkit to show selection
2915 // smartData->frame->invalidateSelection();
2926 * Sets left side of a range selection
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
2932 * @return true if a selection was made and false otherwise
2934 Eina_Bool ewk_frame_selection_right_set(Evas_Object* ewkFrame, int x, int y)
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);
2941 WebCore::FrameSelection* frameSelection = smartData->frame->selection();
2943 if (!frameSelection->isRange())
2946 WebCore::Node* selectionStartNode = frameSelection->start().deprecatedNode();
2947 if (!selectionStartNode || !selectionStartNode->renderer())
2950 WebCore::IntPoint point(x, y);
2952 if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
2953 const int boundariesWidth = 2;
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);
2963 WebCore::VisiblePosition* position = new WebCore::VisiblePosition(smartData->frame->visiblePositionForPoint(point));
2964 WebCore::Position base = frameSelection->base();
2966 WebCore::Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
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);
2980 Eina_Bool oldProhibitsScrolling = smartData->frame->view()->prohibitsScrolling();
2981 smartData->frame->view()->setProhibitsScrolling(true);
2983 frameSelection->setExtent(*position, WebCore::UserTriggered);
2985 smartData->frame->view()->setProhibitsScrolling(oldProhibitsScrolling);
2986 // This forces webkit to show selection
2987 // smartData->frame->invalidateSelection();
2998 * Function clears only a range selection leaving caret selection unchanged
3000 * @param [in] ewkFrame Frame.
3001 * @return true If selection is cleared, false if clearing selection was not possible
3004 Eina_Bool ewk_frame_selection_range_clear(Evas_Object* ewkFrame)
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);
3010 WebCore::FrameSelection* controller = smartData->frame->selection();
3014 if (controller->isRange()) {
3015 if (controller->isContentEditable()) {
3016 WebCore::VisiblePosition visiblePos(controller->extent());
3017 if (visiblePos.isNull())
3019 WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
3020 controller->setSelection(newSelection, WebCore::CharacterGranularity);
3021 controller->setCaretBlinkingSuspended(false);
3023 controller->clear();
3028 LOG_ERROR("TIZEN_TEXT_SELECTION is disabled. \n");
3034 * Function sets caret position to given coordinates
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
3041 Eina_Bool ewk_frame_caret_position_set(Evas_Object* ewkFrame, int x, int y)
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);
3047 WebCore::FrameSelection* controller = smartData->frame->selection();
3051 WebCore::IntPoint point(x, y);
3053 WebCore::HitTestResult result = smartData->frame->eventHandler()->hitTestResultAtPoint
3054 (point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
3056 if (result.scrollbar())
3059 WebCore::Node* innerNode = result.innerNode();
3061 if (!innerNode || !innerNode->renderer())
3064 WebCore::VisiblePosition visiblePos;
3066 const int boundariesWidth = 2;
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);
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
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();
3085 if (!deepInnerNode || !deepInnerNode->renderer())
3088 // so we get a base node rectange
3089 WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
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());
3095 // if we are outside the rect we cheat, that we are just inside of it
3098 else if (point.y() >= deepNodeRect.height())
3099 point.setY(deepNodeRect.height() - 1);
3101 // visible position created - caret ready to set
3102 visiblePos = deepInnerNode->renderer()->positionForPoint(point);
3103 if (visiblePos.isNull())
3106 // for plain text input fields we can get only a caret bounding box
3107 if (!controller->isCaret() || !controller->caretRenderer())
3110 const WebCore::Node* node = controller->start().deprecatedNode();
3111 if (!node || !node->renderer())
3114 WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
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);
3126 // hit test with fake (adjusted) coordinates
3127 WebCore::HitTestResult newResult = smartData->frame->eventHandler()->hitTestResultAtPoint
3128 (point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
3130 if (!newResult.isContentEditable())
3133 WebCore::Node* newInnerNode = newResult.innerNode();
3135 if (!newInnerNode || !newInnerNode->renderer())
3138 // visible position created
3139 visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
3140 if (visiblePos.isNull())
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);
3152 LOG_ERROR("TIZEN_TEXT_CARET_HANDLING is disabled. \n");
3158 * Function gets current text caret coordinates
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
3167 Eina_Bool ewk_frame_caret_position_get(Evas_Object* ewkFrame, int* x, int* y, int* width, int* height)
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);
3177 WebCore::FrameSelection* controller = smartData->frame->selection();
3181 WebCore::Node* node = controller->start().deprecatedNode();
3182 if (!node || !node->renderer() || !node->isContentEditable())
3185 WebCore::IntRect rect;
3187 if (controller->isCaret())
3188 rect = controller->absoluteCaretBounds();
3194 *width = rect.width();
3195 *height = rect.height();
3199 LOG_ERROR("TIZEN_TEXT_CARET_HANDLING is disabled. \n");
3205 * Queries if the given points are located in the same paragraph.
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
3213 * @return @c true if the points are located in the same paragraph, @c false if not or on failure
3215 Eina_Bool ewk_frame_points_in_same_paragraph_get(Evas_Object* ewkFrame, int x1, int y1, int x2, int y2)
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);
3221 WebCore::IntPoint p1(x1, y1);
3222 WebCore::IntPoint p2(x2, y2);
3224 return inSameParagraph(smartData->frame->visiblePositionForPoint(p1, true), smartData->frame->visiblePositionForPoint(p2, true));
3226 LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3232 * Gets paragraph as a rectangle for the given point.
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
3239 * @return @c true on success or false on failure
3241 Eina_Bool ewk_frame_paragraph_rect_get(Evas_Object* ewkFrame, int x, int y, Eina_Rectangle* paragraph_rect)
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);
3248 WebCore::IntPoint p(x, y);
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;
3260 LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3265 Eina_Bool ewk_frame_focus_ring_invalidate(Evas_Object *ewkFrame)
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);
3271 WebCore::Node* pressNode = smartData->frame->eventHandler()->mousePressNode();
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);
3290 * Gets paragraph selection rectangle containing already selected text
3292 * @param [in] ewkFrame frame smart object
3293 * @param [out] paragraph_rect the pointer to store paragraph, must @b not be @c 0
3295 * @return @c true on success or false on failure
3297 Eina_Bool ewk_frame_paragraph_selection_rect_get(Evas_Object* ewkFrame, Eina_Rectangle* paragraph_rect)
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);
3303 if (!smartData->frame->selection()->isRange())
3306 // Is this check necessary? Leaving it for safety.
3307 WebCore::RenderView* root = smartData->frame->contentRenderer();
3311 RefPtr<WebCore::Range> selectedRange = smartData->frame->selection()->toNormalizedRange();
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!
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();
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();
3334 paragraph_rect->w = x2 - paragraph_rect->x;
3335 paragraph_rect->h = y2 - paragraph_rect->y;
3339 LOG_ERROR("TIZEN_PARAGRAPH_SELECTION is disabled. \n");
3346 * Reports submit button clicked.
3348 * Emits signal: "submit,clicked".
3350 void ewk_frame_submit_clicked(Evas_Object* ewkFrame, const char* username, const char* password, const char* url)
3352 #if ENABLE(TIZEN_PASSWORD_MANAGER)
3353 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3354 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
3361 evas_object_smart_callback_call(ewkFrame, "submit,clicked", tab);
3363 LOG_ERROR("TIZEN_PASSWORD_MANAGER is disabled. \n");
3367 void ewk_frame_geolocation_allowed_set(Evas_Object* ewkFrame, Eina_Bool allowed)
3369 #if ENABLE(TIZEN_GEOLOCATION)
3370 WebCore::Frame* frame = ewk_frame_core_get(ewkFrame);
3374 if (!frame->domWindow() || !frame->domWindow()->navigator())
3377 WebCore::Geolocation* geolocation = WebCore::NavigatorGeolocation::from(frame->domWindow()->navigator())->geolocation();
3379 geolocation->setIsAllowed(allowed);
3383 #if ENABLE(TIZEN_WEBKIT_EFL_DRT)
3385 * Returns counter value for element
3387 * @param ewkFrame Frame
3388 * @param element_id element id
3390 * @return returns newly-allocated string or NULL on error
3392 char *ewk_frame_counter_value_by_element_id_get(const Evas_Object *ewkFrame, const char *element_id)
3394 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3396 WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(element_id));
3400 return strdup(WebCore::counterValueForElement(element).utf8().data());
3404 * Dumps webpage's layout as a plain text
3406 * @param ewkFrame Frame
3408 * @return returns newly-allocated string or NULL on error
3410 WTF::String ewk_frame_inner_text_get(const Evas_Object *ewkFrame)
3412 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, WTF::String());
3414 WebCore::FrameView *frameView = smartData->frame->view();
3415 if (frameView && frameView->layoutPending())
3416 frameView->layout();
3418 WebCore::Element *documentElement = smartData->frame->document()->documentElement();
3419 if (!documentElement)
3422 return documentElement->innerText();
3426 * Dumps webpage's layout as a tree representation
3428 * @param ewkFrame Frame
3430 * @return returns newly-allocated string or NULL on error
3432 char *ewk_frame_render_tree_dump_get(const Evas_Object *ewkFrame)
3434 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3436 WebCore::FrameView *frameView = smartData->frame->view();
3437 if (frameView && frameView->layoutPending())
3438 frameView->layout();
3440 return strdup(WebCore::externalRepresentation(smartData->frame).utf8().data());
3444 * Returns child frames if exists
3446 * @param ewkFrame Frame
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.
3451 Eina_List *ewk_frame_children_get(const Evas_Object *ewkFrame)
3453 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3455 Eina_List *childFrames = 0;
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());
3462 childFrames = eina_list_append(childFrames, client->webFrame());
3469 * Returns number of page element
3471 * @param ewkFrame Frame
3472 * @param element_id element id
3473 * @param pageWidth page width
3474 * @param pageHeight page height
3476 * @return number of page element or @c 0 on error
3478 int ewk_frame_page_number_by_element_id_get(const Evas_Object *ewkFrame, const char *element_id, float pageWidth, float pageHeight)
3480 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3481 WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(element_id));
3485 return WebCore::PrintContext::pageNumberForElement(element, WebCore::FloatSize(pageWidth, pageHeight));
3489 * Returns number of pages
3491 * @param ewkFrame Frame
3492 * @param pageWidth page width
3493 * @param pageHeight page height
3495 * @return returns number of pages or 0 on error
3497 int ewk_frame_page_number_get(const Evas_Object *ewkFrame, float pageWidth, float pageHeight)
3499 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3501 return WebCore::PrintContext::numberOfPages(smartData->frame, WebCore::FloatSize(pageWidth, pageHeight));
3505 * Set pause on frame's animation
3508 * @param element_id element id
3511 * @return returns @c TRUE if animation was paused, @c FALSE otherwise
3513 Eina_Bool ewk_frame_animation_pause(const Evas_Object *ewkFrame, const char *name, const char *elementId, double time)
3515 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3517 WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(elementId));
3518 if (!element || !element->renderer())
3521 return smartData->frame->animation()->pauseAnimationAtTime(element->renderer(), WTF::AtomicString(name), time);
3527 * @param ewkFrame Frame
3532 * @return returns @c TRUE if CSS transition was paused, @c FALSE otherwise
3534 Eina_Bool ewk_frame_transition_pause(const Evas_Object *ewkFrame, const char *name, const char *elementId, double time)
3536 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3538 WebCore::Element *element = smartData->frame->document()->getElementById(WTF::AtomicString(elementId));
3539 if (!element || !element->renderer())
3542 return smartData->frame->animation()->pauseTransitionAtTime(element->renderer(), WTF::AtomicString(name), time);
3546 * Returns number of active animations
3548 * @param ewkFrame Frame
3550 * @return returns number of active animations, or @c 0 if something went wrong
3552 unsigned ewk_frame_animation_active_number_get(const Evas_Object *ewkFrame)
3554 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3556 WebCore::AnimationController *aController = smartData->frame->animation();
3560 return aController->numberOfActiveAnimations(smartData->frame->document());
3564 * Suspend animations.
3566 * @param ewkFrame Frame
3568 void ewk_frame_animation_suspend(const Evas_Object *ewkFrame)
3570 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3572 WebCore::AnimationController *aController = smartData->frame->animation();
3574 aController->suspendAnimations();
3578 * Resume animations.
3580 * @param ewkFrame Frame
3582 void ewk_frame_animation_resume(const Evas_Object *ewkFrame)
3584 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3586 WebCore::AnimationController *aController = smartData->frame->animation();
3588 aController->resumeAnimations();
3592 * Gets response MIME type
3594 * @param ewkFrame Frame
3596 * @return returns newly-allocated string or NULL on error.
3598 char *ewk_frame_response_mime_type_get(const Evas_Object *ewkFrame)
3600 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3602 WebCore::DocumentLoader *docLoader = smartData->frame->loader()->documentLoader();
3606 WTF::String mimeType = docLoader->responseMIMEType();
3607 if (mimeType.length() > 0)
3608 return strdup(mimeType.utf8().data());
3614 * Clears the opener for a given frame;
3616 * @param ewkFrame Frame
3618 void ewk_frame_opener_clear(const Evas_Object *ewkFrame)
3620 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3622 if (smartData->frame)
3623 smartData->frame->loader()->setOpener(0);
3627 * Gets the rectangle for the current selection.
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
3636 Eina_Bool ewk_frame_selection_rectangle_get(const Evas_Object *ewkFrame, int *x, int *y, int *width, int *height)
3638 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, false);
3640 if (!smartData->frame)
3643 WebCore::IntRect bounds = enclosingIntRect(smartData->frame->selection()->bounds());
3649 *width = bounds.width();
3651 *height = bounds.height();
3659 unsigned int ewk_frame_pending_unload_event_count_get(const Evas_Object *ewkFrame)
3661 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3663 return smartData->frame->domWindow()->pendingUnloadEventListeners();
3669 WTF::String ewk_frame_suitable_drt_name_get(const Evas_Object *ewkFrame)
3671 // Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm
3672 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, WTF::String());
3674 const String frameName(ewk_frame_name_get(ewkFrame));
3676 if (ewkFrame == ewk_view_frame_main_get(smartData->view)) {
3677 if (!frameName.isEmpty())
3678 return WTF::String("main frame \"") + frameName + WTF::String("\"");
3680 return WTF::String("main frame");
3683 if (!frameName.isEmpty())
3684 return WTF::String("frame \"") + frameName + WTF::String("\"");
3686 return WTF::String("frame (anonymous)");
3691 * Clear the name associated with the given frame.
3693 * The name can be set by a page if it changes the window.name attribute, for example.
3695 * @param ewkFrame The ewk frame to act upon.
3697 void ewk_frame_name_clear(Evas_Object *ewkFrame)
3699 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3700 smartData->frame->tree()->clearName();
3705 void ewk_frame_virtual_mouse_down_position_set(Evas_Object* ewkFrame, int x, int y)
3707 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL)
3708 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3709 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
3711 smartData->frame->eventHandler()->setMousePressNodeAtPoint(WebCore::IntPoint(x, y));
3717 * Defines whether the frame has displayed mixed content.
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.
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.
3725 * Emits signal: "mixedcontent,displayed" with no parameters when @p hasDisplayed is @c true.
3727 void ewk_frame_mixed_content_displayed_set(Evas_Object* ewkFrame, bool hasDisplayed)
3729 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3730 smartData->hasDisplayedMixedContent = hasDisplayed;
3733 ewk_view_mixed_content_displayed_set(smartData->view, true);
3734 evas_object_smart_callback_call(ewkFrame, "mixedcontent,displayed", 0);
3740 * Defines whether the frame has run mixed content.
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.
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.
3748 * Emits signal: "mixedcontent,run" with no parameters when @p hasRun is @c true.
3750 void ewk_frame_mixed_content_run_set(Evas_Object* ewkFrame, bool hasRun)
3752 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
3753 smartData->hasRunMixedContent = hasRun;
3756 ewk_view_mixed_content_run_set(smartData->view, true);
3757 evas_object_smart_callback_call(ewkFrame, "mixedcontent,run", 0);
3763 * Reports that reflected XSS is encountered in the page and suppressed.
3765 * @param xssInfo Information received from the XSSAuditor when XSS is
3766 * encountered in the page.
3768 * Emits signal: "xss,detected" with pointer to Ewk_Frame_Xss_Notification.
3770 void ewk_frame_xss_detected(Evas_Object* ewkFrame, const Ewk_Frame_Xss_Notification* xssInfo)
3772 evas_object_smart_callback_call(ewkFrame, "xss,detected", (void*)xssInfo);
3775 namespace EWKPrivate {
3777 WebCore::Frame* coreFrame(const Evas_Object* ewkFrame)
3779 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
3780 return smartData->frame;
3783 Evas_Object* kitFrame(const WebCore::Frame* coreFrame)
3788 WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(coreFrame);
3789 if (!frameLoaderClient)
3792 return frameLoaderClient->webFrame();
3795 } // namespace EWKPrivate