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 "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 "PlatformKeyboardEvent.h"
43 #include "PlatformMouseEvent.h"
44 #include "PlatformTouchEvent.h"
45 #include "PlatformWheelEvent.h"
46 #include "ProgressTracker.h"
48 #include "ResourceRequest.h"
49 #include "ScriptValue.h"
50 #include "SharedBuffer.h"
51 #include "SubstituteData.h"
52 #include "WindowsKeyboardCodes.h"
53 #include "ewk_private.h"
58 #include <eina_safety_checks.h>
59 #include <wtf/text/CString.h>
61 static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame";
63 struct Ewk_Frame_Smart_Data {
64 Evas_Object_Smart_Clipped_Data base;
67 #ifdef EWK_FRAME_DEBUG
70 WebCore::Frame* frame;
74 Eina_Bool editable : 1;
77 struct Eina_Iterator_Ewk_Frame {
80 unsigned currentIndex;
83 #ifndef EWK_TYPE_CHECK
84 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) do { } while (0)
86 #define EWK_FRAME_TYPE_CHECK(ewkFrame, ...) \
88 const char* _tmp_otype = evas_object_type_get(ewkFrame); \
89 if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) { \
91 ("%p (%s) is not of an ewk_frame!", ewkFrame, \
92 _tmp_otype ? _tmp_otype : "(null)"); \
98 #define EWK_FRAME_SD_GET(ewkFrame, ptr) \
99 Ewk_Frame_Smart_Data* ptr = static_cast<Ewk_Frame_Smart_Data*>(evas_object_smart_data_get(ewkFrame))
101 #define EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, ptr, ...) \
102 EWK_FRAME_TYPE_CHECK(ewkFrame, __VA_ARGS__); \
103 EWK_FRAME_SD_GET(ewkFrame, ptr); \
105 CRITICAL("no smart data for object %p (%s)", \
106 ewkFrame, evas_object_type_get(ewkFrame)); \
107 return __VA_ARGS__; \
110 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
112 #ifdef EWK_FRAME_DEBUG
113 static inline void _ewk_frame_debug(Evas_Object* ewkFrame)
115 Evas_Object* clip, * parent;
116 Evas_Coord x, y, width, height, contentX, contentY, contentWidth, contentHeight;
117 int red, green, blue, alpha, contentRed, contentGreen, contentBlue, contentAlpha;
119 evas_object_color_get(ewkFrame, &red, &green, &blue, &alpha);
120 evas_object_geometry_get(ewkFrame, &x, &y, &width, &height);
122 clip = evas_object_clip_get(ewkFrame);
123 evas_object_color_get(clip, &contentRed, &contentGreen, &contentBlue, &contentAlpha);
124 evas_object_geometry_get(clip, &contentX, &contentY, &contentWidth, &contentHeight);
126 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",
127 ewkFrame, evas_object_type_get(ewkFrame), evas_object_name_get(ewkFrame), evas_object_visible_get(ewkFrame),
128 red, green, blue, alpha, x, y, width, height,
129 clip, evas_object_visible_get(clip), contentRed, contentGreen, contentBlue, contentAlpha, contentX, contentY, contentWidth, contentHeight);
130 parent = evas_object_smart_parent_get(ewkFrame);
132 fprintf(stderr, "\n");
134 _ewk_frame_debug(parent);
138 static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(const WebCore::Frame* frame)
140 return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client());
143 static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* iterator, Evas_Object** data)
145 EWK_FRAME_SD_GET_OR_RETURN(iterator->object, smartData, EINA_FALSE);
146 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
148 WebCore::FrameTree* tree = smartData->frame->tree(); // check if it's still valid
149 EINA_SAFETY_ON_NULL_RETURN_VAL(tree, EINA_FALSE);
151 if (iterator->currentIndex < tree->childCount()) {
152 *data = EWKPrivate::kitFrame(tree->child(iterator->currentIndex++));
159 static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* iterator)
161 return iterator->object;
164 static void _ewk_frame_smart_add(Evas_Object* ewkFrame)
166 EWK_FRAME_SD_GET(ewkFrame, smartData);
169 smartData = static_cast<Ewk_Frame_Smart_Data*>(calloc(1, sizeof(Ewk_Frame_Smart_Data)));
171 CRITICAL("could not allocate Ewk_Frame_Smart_Data");
174 evas_object_smart_data_set(ewkFrame, smartData);
177 smartData->self = ewkFrame;
179 _parent_sc.add(ewkFrame);
180 evas_object_static_clip_set(smartData->base.clipper, EINA_FALSE);
181 evas_object_move(smartData->base.clipper, 0, 0);
182 evas_object_resize(smartData->base.clipper, 0, 0);
184 #ifdef EWK_FRAME_DEBUG
185 smartData->region = evas_object_rectangle_add(smartData->base.evas);
189 evas_object_color_set(smartData->region, 128, 0, 0, 128);
192 evas_object_color_set(smartData->region, 0, 128, 0, 128);
195 evas_object_color_set(smartData->region, 0, 0, 128, 128);
198 evas_object_color_set(smartData->region, 128, 0, 0, 128);
201 evas_object_color_set(smartData->region, 128, 128, 0, 128);
204 evas_object_color_set(smartData->region, 128, 0, 128, 128);
207 evas_object_color_set(smartData->region, 0, 128, 128, 128);
216 evas_object_smart_member_add(smartData->region, ewkFrame);
217 evas_object_hide(smartData->region);
221 static void _ewk_frame_smart_del(Evas_Object* ewkFrame)
223 EWK_FRAME_SD_GET(ewkFrame, smartData);
226 if (smartData->frame) {
227 WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(smartData->frame);
229 smartData->frame->loader()->detachFromParent();
230 smartData->frame->loader()->cancelAndClear();
231 smartData->frame = 0;
234 eina_stringshare_del(smartData->title);
235 eina_stringshare_del(smartData->uri);
236 eina_stringshare_del(smartData->name);
239 _parent_sc.del(ewkFrame);
242 static void _ewk_frame_smart_resize(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
244 EWK_FRAME_SD_GET(ewkFrame, smartData);
245 evas_object_resize(smartData->base.clipper, width, height);
247 #ifdef EWK_FRAME_DEBUG
248 evas_object_resize(smartData->region, width, height);
250 evas_object_geometry_get(smartData->region, &x, &y, &width, &height);
251 INF("region=%p, visible=%d, geo=%d,%d + %dx%d",
252 smartData->region, evas_object_visible_get(smartData->region), x, y, width, height);
253 _ewk_frame_debug(ewkFrame);
257 static void _ewk_frame_smart_set(Evas_Smart_Class* api)
259 evas_object_smart_clipped_smart_set(api);
260 api->add = _ewk_frame_smart_add;
261 api->del = _ewk_frame_smart_del;
262 api->resize = _ewk_frame_smart_resize;
265 static inline Evas_Smart* _ewk_frame_smart_class_new(void)
267 static Evas_Smart_Class smartClass = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR);
268 static Evas_Smart* smart = 0;
270 if (EINA_UNLIKELY(!smart)) {
271 evas_object_smart_clipped_smart_set(&_parent_sc);
272 _ewk_frame_smart_set(&smartClass);
273 smart = evas_smart_class_new(&smartClass);
279 Evas_Object* ewk_frame_view_get(const Evas_Object* ewkFrame)
281 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, 0);
285 Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* ewkFrame)
287 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
288 Eina_Iterator_Ewk_Frame* iterator = static_cast<Eina_Iterator_Ewk_Frame*>
289 (calloc(1, sizeof(Eina_Iterator_Ewk_Frame)));
293 EINA_MAGIC_SET(&iterator->base, EINA_MAGIC_ITERATOR);
294 iterator->base.next = FUNC_ITERATOR_NEXT(_ewk_frame_children_iterator_next);
295 iterator->base.get_container = FUNC_ITERATOR_GET_CONTAINER(_ewk_frame_children_iterator_get_container);
296 iterator->base.free = FUNC_ITERATOR_FREE(free);
297 iterator->object = ewkFrame;
298 iterator->currentIndex = 0;
299 return &iterator->base;
302 Evas_Object* ewk_frame_child_find(Evas_Object* ewkFrame, const char* name)
304 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
305 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
306 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
307 WTF::String frameName = WTF::String::fromUTF8(name);
308 return EWKPrivate::kitFrame(smartData->frame->tree()->find(WTF::AtomicString(frameName)));
311 Eina_Bool ewk_frame_uri_set(Evas_Object* ewkFrame, const char* uri)
313 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, EINA_FALSE);
314 WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri));
315 WebCore::ResourceRequest req(kurl);
316 WebCore::FrameLoader* loader = sd->frame->loader();
317 loader->load(req, false);
321 const char* ewk_frame_uri_get(const Evas_Object* ewkFrame)
323 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, 0);
327 const char* ewk_frame_title_get(const Evas_Object* ewkFrame)
329 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
330 return smartData->title;
333 const char* ewk_frame_name_get(const Evas_Object* ewkFrame)
335 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
337 if (!smartData->frame) {
338 ERR("could not get name of uninitialized frame.");
342 const WTF::String frameName = smartData->frame->tree()->uniqueName();
344 if ((smartData->name) && (smartData->name == frameName))
345 return smartData->name;
347 eina_stringshare_replace_length(&(smartData->name), frameName.utf8().data(), frameName.length());
349 return smartData->name;
352 Eina_Bool ewk_frame_contents_size_get(const Evas_Object* ewkFrame, Evas_Coord* width, Evas_Coord* height)
358 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, EINA_FALSE);
359 if (!sd->frame || !sd->frame->view())
362 *width = sd->frame->view()->contentsWidth();
364 *height = sd->frame->view()->contentsHeight();
368 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)
370 size_t length = strlen(contents);
371 if (contentsSize < 1 || contentsSize > length)
372 contentsSize = length;
374 mimeType = "text/html";
378 baseUri = "about:blank";
380 WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(baseUri));
381 WebCore::KURL unreachableKURL;
383 unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachableUri));
385 unreachableKURL = WebCore::KURL();
387 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contentsSize);
388 WebCore::SubstituteData substituteData
390 WTF::String::fromUTF8(mimeType),
391 WTF::String::fromUTF8(encoding),
392 baseKURL, unreachableKURL);
393 WebCore::ResourceRequest request(baseKURL);
395 smartData->frame->loader()->load(request, substituteData, false);
399 Eina_Bool ewk_frame_contents_set(Evas_Object* ewkFrame, const char* contents, size_t contentsSize, const char* mimeType, const char* encoding, const char* baseUri)
401 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
402 EINA_SAFETY_ON_FALSE_RETURN_VAL(smartData->frame, EINA_FALSE);
403 EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE);
404 return _ewk_frame_contents_set_internal
405 (smartData, contents, contentsSize, mimeType, encoding, baseUri, 0);
408 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)
410 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
411 EINA_SAFETY_ON_FALSE_RETURN_VAL(smartData->frame, EINA_FALSE);
412 EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE);
413 EINA_SAFETY_ON_NULL_RETURN_VAL(unreachableUri, EINA_FALSE);
414 return _ewk_frame_contents_set_internal
415 (smartData, contents, contentsSize, mimeType, encoding, baseUri,
419 Eina_Bool ewk_frame_script_execute(Evas_Object* ewkFrame, const char* script)
421 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
422 EINA_SAFETY_ON_FALSE_RETURN_VAL(smartData->frame, EINA_FALSE);
423 EINA_SAFETY_ON_NULL_RETURN_VAL(script, EINA_FALSE);
424 smartData->frame->script()->executeScript(WTF::String::fromUTF8(script), true);
428 Eina_Bool ewk_frame_editable_get(const Evas_Object* ewkFrame)
430 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
431 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
432 return smartData->editable;
435 Eina_Bool ewk_frame_editable_set(Evas_Object* ewkFrame, Eina_Bool editable)
437 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
438 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
439 editable = !!editable;
440 if (smartData->editable == editable)
443 smartData->frame->editor()->applyEditingStyleToBodyElement();
447 char* ewk_frame_selection_get(const Evas_Object* ewkFrame)
449 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
450 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
451 WTF::CString s = smartData->frame->editor()->selectedText().utf8();
454 return strdup(s.data());
457 Eina_Bool ewk_frame_text_search(const Evas_Object* ewkFrame, const char* text, Eina_Bool caseSensitive, Eina_Bool forward, Eina_Bool wrap)
459 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
460 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
461 EINA_SAFETY_ON_NULL_RETURN_VAL(text, EINA_FALSE);
463 return smartData->frame->editor()->findString(WTF::String::fromUTF8(text), forward, caseSensitive, wrap, true);
466 unsigned int ewk_frame_text_matches_mark(Evas_Object* ewkFrame, const char* string, Eina_Bool caseSensitive, Eina_Bool highlight, unsigned int limit)
468 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
469 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
470 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
472 smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
473 return smartData->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), caseSensitive, limit, true);
476 Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* ewkFrame)
478 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
479 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
481 smartData->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch);
485 Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* ewkFrame, Eina_Bool highlight)
487 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
488 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
489 smartData->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
493 Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* ewkFrame)
495 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
496 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
497 return smartData->frame->editor()->markedTextMatchesAreHighlighted();
501 * Comparison function used by ewk_frame_text_matches_nth_pos_get
503 static bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& begin, const WebCore::IntRect& end)
505 return (begin.y() < end.y() || (begin.y() == end.y() && begin.x() < end.x()));
509 * Predicate used by ewk_frame_text_matches_nth_pos_get
511 static bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& rect)
513 return (rect.x() < 0 || rect.y() < 0);
516 Eina_Bool ewk_frame_text_matches_nth_pos_get(const Evas_Object* ewkFrame, size_t number, int* x, int* y)
518 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
519 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
521 Vector<WebCore::IntRect> intRects = smartData->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch);
523 /* remove useless values */
524 std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value);
526 if (intRects.isEmpty() || number > intRects.size())
529 std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than);
532 *x = intRects[number - 1].x();
534 *y = intRects[number - 1].y();
538 Eina_Bool ewk_frame_stop(Evas_Object* ewkFrame)
540 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
541 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
542 smartData->frame->loader()->stopAllLoaders();
546 Eina_Bool ewk_frame_reload(Evas_Object* ewkFrame)
548 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
549 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
550 smartData->frame->loader()->reload();
554 Eina_Bool ewk_frame_reload_full(Evas_Object* ewkFrame)
556 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
557 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
558 smartData->frame->loader()->reload(true);
562 Eina_Bool ewk_frame_back(Evas_Object* ewkFrame)
564 return ewk_frame_navigate(ewkFrame, -1);
567 Eina_Bool ewk_frame_forward(Evas_Object* ewkFrame)
569 return ewk_frame_navigate(ewkFrame, 1);
572 Eina_Bool ewk_frame_navigate(Evas_Object* ewkFrame, int steps)
574 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
575 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
576 WebCore::Page* page = smartData->frame->page();
577 if (!page->canGoBackOrForward(steps))
579 page->goBackOrForward(steps);
583 Eina_Bool ewk_frame_back_possible(Evas_Object* ewkFrame)
585 return ewk_frame_navigate_possible(ewkFrame, -1);
588 Eina_Bool ewk_frame_forward_possible(Evas_Object* ewkFrame)
590 return ewk_frame_navigate_possible(ewkFrame, 1);
593 Eina_Bool ewk_frame_navigate_possible(Evas_Object* ewkFrame, int steps)
595 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
596 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
597 WebCore::Page* page = smartData->frame->page();
598 return page->canGoBackOrForward(steps);
601 float ewk_frame_page_zoom_get(const Evas_Object* ewkFrame)
603 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
604 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
605 return smartData->frame->pageZoomFactor();
608 Eina_Bool ewk_frame_page_zoom_set(Evas_Object* ewkFrame, float pageZoomFactor)
610 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
611 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
612 smartData->frame->setPageZoomFactor(pageZoomFactor);
616 float ewk_frame_text_zoom_get(const Evas_Object* ewkFrame)
618 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1.0);
619 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1.0);
620 return smartData->frame->textZoomFactor();
623 Eina_Bool ewk_frame_text_zoom_set(Evas_Object* ewkFrame, float textZoomFactor)
625 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
626 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
627 smartData->frame->setTextZoomFactor(textZoomFactor);
631 void ewk_frame_hit_test_free(Ewk_Hit_Test* hitTest)
633 EINA_SAFETY_ON_NULL_RETURN(hitTest);
634 eina_stringshare_del(hitTest->title);
635 eina_stringshare_del(hitTest->alternate_text);
636 eina_stringshare_del(hitTest->link.text);
637 eina_stringshare_del(hitTest->link.url);
638 eina_stringshare_del(hitTest->link.title);
639 eina_stringshare_del(hitTest->image_uri);
640 eina_stringshare_del(hitTest->media_uri);
644 Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* ewkFrame, int x, int y)
646 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
647 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
649 WebCore::FrameView* view = smartData->frame->view();
650 EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
651 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->contentRenderer(), 0);
653 WebCore::HitTestResult result = smartData->frame->eventHandler()->hitTestResultAtPoint
654 (view->windowToContents(WebCore::IntPoint(x, y)),
655 /*allowShadowContent*/ false, /*ignoreClipping*/ true);
657 if (result.scrollbar())
659 if (!result.innerNode())
662 Ewk_Hit_Test* hitTest = static_cast<Ewk_Hit_Test*>(calloc(1, sizeof(Ewk_Hit_Test)));
664 CRITICAL("Could not allocate memory for hit test.");
668 hitTest->x = result.point().x();
669 hitTest->y = result.point().y();
672 hitTest->bounding_box.x = result.boundingBox().x();
673 hitTest->bounding_box.y = result.boundingBox().y();
674 hitTest->bounding_box.width = result.boundingBox().width();
675 hitTest->bounding_box.height = result.boundingBox().height();
677 hitTest->bounding_box.x = 0;
678 hitTest->bounding_box.y = 0;
679 hitTest->bounding_box.w = 0;
680 hitTest->bounding_box.h = 0;
683 WebCore::TextDirection direction;
684 hitTest->title = eina_stringshare_add(result.title(direction).utf8().data());
685 hitTest->alternate_text = eina_stringshare_add(result.altDisplayString().utf8().data());
686 if (result.innerNonSharedNode() && result.innerNonSharedNode()->document()
687 && result.innerNonSharedNode()->document()->frame())
688 hitTest->frame = EWKPrivate::kitFrame(result.innerNonSharedNode()->document()->frame());
690 hitTest->link.text = eina_stringshare_add(result.textContent().utf8().data());
691 hitTest->link.url = eina_stringshare_add(result.absoluteLinkURL().string().utf8().data());
692 hitTest->link.title = eina_stringshare_add(result.titleDisplayString().utf8().data());
693 hitTest->link.target_frame = EWKPrivate::kitFrame(result.targetFrame());
695 hitTest->image_uri = eina_stringshare_add(result.absoluteImageURL().string().utf8().data());
696 hitTest->media_uri = eina_stringshare_add(result.absoluteMediaURL().string().utf8().data());
698 int context = EWK_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
700 if (!result.absoluteLinkURL().isEmpty())
701 context |= EWK_HIT_TEST_RESULT_CONTEXT_LINK;
702 if (!result.absoluteImageURL().isEmpty())
703 context |= EWK_HIT_TEST_RESULT_CONTEXT_IMAGE;
704 if (!result.absoluteMediaURL().isEmpty())
705 context |= EWK_HIT_TEST_RESULT_CONTEXT_MEDIA;
706 if (result.isSelected())
707 context |= EWK_HIT_TEST_RESULT_CONTEXT_SELECTION;
708 if (result.isContentEditable())
709 context |= EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE;
711 hitTest->context = static_cast<Ewk_Hit_Test_Result_Context>(context);
717 ewk_frame_scroll_add(Evas_Object* ewkFrame, int deltaX, int deltaY)
719 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
720 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
721 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
722 smartData->frame->view()->scrollBy(WebCore::IntSize(deltaX, deltaY));
727 ewk_frame_scroll_set(Evas_Object* ewkFrame, int x, int y)
729 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
730 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
731 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
732 smartData->frame->view()->setScrollPosition(WebCore::IntPoint(x, y));
737 ewk_frame_scroll_size_get(const Evas_Object* ewkFrame, int* width, int* height)
743 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
744 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
745 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
746 WebCore::IntPoint point = smartData->frame->view()->maximumScrollPosition();
755 ewk_frame_scroll_pos_get(const Evas_Object* ewkFrame, int* x, int* y)
761 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
762 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
763 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
764 WebCore::IntPoint pos = smartData->frame->view()->scrollPosition();
772 Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* ewkFrame, Eina_Bool includeScrollbars, int* x, int* y, int* width, int* height)
782 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
783 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
784 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
785 WebCore::IntRect rect = smartData->frame->view()->visibleContentRect(includeScrollbars);
791 *width = rect.width();
793 *height = rect.height();
797 Eina_Bool ewk_frame_paint_full_get(const Evas_Object* ewkFrame)
799 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
800 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
801 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->view(), EINA_FALSE);
802 return smartData->frame->view()->paintsEntireContents();
805 void ewk_frame_paint_full_set(Evas_Object* ewkFrame, Eina_Bool flag)
807 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
808 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
809 EINA_SAFETY_ON_NULL_RETURN(smartData->frame->view());
810 smartData->frame->view()->setPaintsEntireContents(flag);
813 Eina_Bool ewk_frame_feed_focus_in(Evas_Object* ewkFrame)
815 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
816 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
817 WebCore::FocusController* c = smartData->frame->page()->focusController();
818 c->setFocusedFrame(smartData->frame);
822 Eina_Bool ewk_frame_feed_focus_out(Evas_Object* ewkFrame)
824 // TODO: what to do on focus out?
829 Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* ewkFrame, const Evas_Event_Mouse_Wheel* wheelEvent)
831 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
832 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
833 EINA_SAFETY_ON_NULL_RETURN_VAL(wheelEvent, EINA_FALSE);
835 WebCore::FrameView* view = smartData->frame->view();
836 DBG("ewkFrame=%p, view=%p, direction=%d, z=%d, pos=%d,%d",
837 ewkFrame, view, wheelEvent->direction, wheelEvent->z, wheelEvent->canvas.x, wheelEvent->canvas.y);
838 EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
840 WebCore::PlatformWheelEvent event(wheelEvent);
841 return smartData->frame->eventHandler()->handleWheelEvent(event);
844 Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* ewkFrame, const Evas_Event_Mouse_Down* downEvent)
846 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
847 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
848 EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, EINA_FALSE);
850 WebCore::FrameView* view = smartData->frame->view();
851 DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
852 ewkFrame, view, downEvent->button, downEvent->canvas.x, downEvent->canvas.y);
853 EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
856 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
858 WebCore::PlatformMouseEvent event(downEvent, WebCore::IntPoint(x, y));
859 return smartData->frame->eventHandler()->handleMousePressEvent(event);
862 Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* ewkFrame, const Evas_Event_Mouse_Up* upEvent)
864 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
865 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
866 EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, EINA_FALSE);
868 WebCore::FrameView* view = smartData->frame->view();
869 DBG("ewkFrame=%p, view=%p, button=%d, pos=%d,%d",
870 ewkFrame, view, upEvent->button, upEvent->canvas.x, upEvent->canvas.y);
871 EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
874 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
876 WebCore::PlatformMouseEvent event(upEvent, WebCore::IntPoint(x, y));
877 return smartData->frame->eventHandler()->handleMouseReleaseEvent(event);
880 Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* ewkFrame, const Evas_Event_Mouse_Move* moveEvent)
882 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
883 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
884 EINA_SAFETY_ON_NULL_RETURN_VAL(moveEvent, EINA_FALSE);
886 WebCore::FrameView* view = smartData->frame->view();
887 DBG("ewkFrame=%p, view=%p, pos: old=%d,%d, new=%d,%d, buttons=%d",
888 ewkFrame, view, moveEvent->cur.canvas.x, moveEvent->cur.canvas.y,
889 moveEvent->prev.canvas.x, moveEvent->prev.canvas.y, moveEvent->buttons);
890 EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
893 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
895 WebCore::PlatformMouseEvent event(moveEvent, WebCore::IntPoint(x, y));
896 return smartData->frame->eventHandler()->mouseMoved(event);
899 Eina_Bool ewk_frame_feed_touch_event(Evas_Object* ewkFrame, Ewk_Touch_Event_Type action, Eina_List* points, int metaState)
901 Eina_Bool result = EINA_FALSE;
903 #if ENABLE(TOUCH_EVENTS)
904 EINA_SAFETY_ON_NULL_RETURN_VAL(points, EINA_FALSE);
905 EWK_FRAME_SD_GET(ewkFrame, smartData);
907 if (!smartData || !smartData->frame || !ewk_view_need_touch_events_get(smartData->view))
911 evas_object_geometry_get(smartData->view, &x, &y, 0, 0);
913 WebCore::TouchEventType type = WebCore::TouchStart;
915 case EWK_TOUCH_START:
916 type = WebCore::TouchStart;
919 type = WebCore::TouchEnd;
922 type = WebCore::TouchMove;
924 case EWK_TOUCH_CANCEL:
925 type = WebCore::TouchCancel;
931 WebCore::PlatformTouchEvent touchEvent(points, WebCore::IntPoint(x, y), type, metaState);
932 result = smartData->frame->eventHandler()->handleTouchEvent(touchEvent);
937 static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent& keyEvent)
939 WebCore::ScrollDirection direction;
940 WebCore::ScrollGranularity granularity;
942 int keyCode = keyEvent.windowsVirtualKeyCode();
946 granularity = WebCore::ScrollByPage;
947 if (keyEvent.shiftKey())
948 direction = WebCore::ScrollUp;
950 direction = WebCore::ScrollDown;
953 granularity = WebCore::ScrollByPage;
954 direction = WebCore::ScrollDown;
957 granularity = WebCore::ScrollByPage;
958 direction = WebCore::ScrollUp;
961 granularity = WebCore::ScrollByDocument;
962 direction = WebCore::ScrollUp;
965 granularity = WebCore::ScrollByDocument;
966 direction = WebCore::ScrollDown;
969 granularity = WebCore::ScrollByLine;
970 direction = WebCore::ScrollLeft;
973 granularity = WebCore::ScrollByLine;
974 direction = WebCore::ScrollRight;
977 direction = WebCore::ScrollUp;
978 if (keyEvent.ctrlKey())
979 granularity = WebCore::ScrollByDocument;
981 granularity = WebCore::ScrollByLine;
984 direction = WebCore::ScrollDown;
985 if (keyEvent.ctrlKey())
986 granularity = WebCore::ScrollByDocument;
988 granularity = WebCore::ScrollByLine;
994 if (frame->eventHandler()->scrollOverflow(direction, granularity))
997 frame->view()->scroll(direction, granularity);
1001 Eina_Bool ewk_frame_feed_key_down(Evas_Object* ewkFrame, const Evas_Event_Key_Down* downEvent)
1003 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
1004 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
1005 EINA_SAFETY_ON_NULL_RETURN_VAL(downEvent, EINA_FALSE);
1007 DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1008 ewkFrame, downEvent->keyname, downEvent->key ? downEvent->key : "", downEvent->string ? downEvent->string : "");
1010 WebCore::PlatformKeyboardEvent event(downEvent);
1011 if (smartData->frame->eventHandler()->keyEvent(event))
1014 return _ewk_frame_handle_key_scrolling(smartData->frame, event);
1017 Eina_Bool ewk_frame_feed_key_up(Evas_Object* ewkFrame, const Evas_Event_Key_Up* upEvent)
1019 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
1020 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EINA_FALSE);
1021 EINA_SAFETY_ON_NULL_RETURN_VAL(upEvent, EINA_FALSE);
1023 DBG("ewkFrame=%p keyname=%s (key=%s, string=%s)",
1024 ewkFrame, upEvent->keyname, upEvent->key ? upEvent->key : "", upEvent->string ? upEvent->string : "");
1026 WebCore::PlatformKeyboardEvent event(upEvent);
1027 return smartData->frame->eventHandler()->keyEvent(event);
1030 Ewk_Text_Selection_Type ewk_frame_text_selection_type_get(const Evas_Object* ewkFrame)
1032 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EWK_TEXT_SELECTION_NONE);
1033 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, EWK_TEXT_SELECTION_NONE);
1035 WebCore::FrameSelection* controller = smartData->frame->selection();
1037 return EWK_TEXT_SELECTION_NONE;
1039 switch (controller->selectionType()) {
1040 case WebCore::VisibleSelection::CaretSelection:
1041 return EWK_TEXT_SELECTION_CARET;
1042 case WebCore::VisibleSelection::RangeSelection:
1043 return EWK_TEXT_SELECTION_RANGE;
1045 return EWK_TEXT_SELECTION_NONE;
1049 /* internal methods ****************************************************/
1054 * Creates a new EFL WebKit Frame object.
1056 * Frames are low level entries contained in a page that is contained
1057 * by a view. Usually one operates on the view and not directly on the
1060 * @param canvas canvas where to create the frame object
1062 * @return a new frame object or @c 0 on failure
1064 Evas_Object* ewk_frame_add(Evas* canvas)
1066 return evas_object_smart_add(canvas, _ewk_frame_smart_class_new());
1072 * Initialize frame based on actual WebKit frame.
1074 * This is internal and should never be called by external users.
1076 Eina_Bool ewk_frame_init(Evas_Object* ewkFrame, Evas_Object* view, WebCore::Frame* frame)
1078 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, EINA_FALSE);
1079 if (!smartData->frame) {
1080 WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(frame);
1081 frameLoaderClient->setWebFrame(ewkFrame);
1082 smartData->frame = frame;
1083 smartData->view = view;
1088 ERR("frame %p already set for %p, ignored new %p",
1089 smartData->frame, ewkFrame, frame);
1096 * Adds child to the frame.
1098 Eina_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)
1100 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1103 WebCore::Frame* coreFrame;
1105 frame = ewk_frame_add(smartData->base.evas);
1107 ERR("Could not create ewk_frame object.");
1111 coreFrame = child.get();
1112 if (coreFrame->tree())
1113 coreFrame->tree()->setName(name);
1115 ERR("no tree for child object");
1116 smartData->frame->tree()->appendChild(child);
1118 if (!ewk_frame_init(frame, smartData->view, coreFrame)) {
1119 evas_object_del(frame);
1122 snprintf(buffer, sizeof(buffer), "EWK_Frame:child/%s", name.utf8().data());
1123 evas_object_name_set(frame, buffer);
1124 evas_object_smart_member_add(frame, ewkFrame);
1125 evas_object_show(frame);
1127 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1128 if (!coreFrame->page()) {
1129 evas_object_del(frame);
1133 smartData->frame->loader()->loadURLIntoChildFrame(url, referrer, coreFrame);
1135 // The frame's onload handler may have removed it from the document.
1136 // See fast/dom/null-page-show-modal-dialog-crash.html for an example.
1137 if (!coreFrame->tree()->parent()) {
1138 evas_object_del(frame);
1142 // TODO: announce frame was created?
1148 * Change the ewk view this frame is associated with.
1150 * @param ewkFrame The ewk frame to act upon.
1151 * @param newParent The new view that will be set as the parent of the frame.
1153 void ewk_frame_view_set(Evas_Object* ewkFrame, Evas_Object* newParent)
1155 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1157 evas_object_smart_member_del(ewkFrame);
1158 evas_object_smart_member_add(ewkFrame, newParent);
1160 smartData->view = newParent;
1165 * Frame was destroyed by loader, remove internal reference.
1167 void ewk_frame_core_gone(Evas_Object* ewkFrame)
1169 DBG("ewkFrame=%p", ewkFrame);
1170 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1171 smartData->frame = 0;
1176 * Reports a resource will be requested. User may override behavior of webkit by
1177 * changing values in @param request.
1179 * @param ewkFrame Frame.
1180 * @param request Request details that user may override. Whenever values on
1181 * this struct changes, it must be properly malloc'd as it will be freed
1184 * Emits signal: "resource,request,willsend"
1186 void ewk_frame_request_will_send(Evas_Object* ewkFrame, Ewk_Frame_Resource_Request* request)
1188 evas_object_smart_callback_call(ewkFrame, "resource,request,willsend", request);
1193 * Reports that there's a new resource.
1195 * @param ewkFrame Frame.
1196 * @param request New request details. No changes are allowed to fields.
1198 * Emits signal: "resource,request,new"
1200 void ewk_frame_request_assign_identifier(Evas_Object* ewkFrame, const Ewk_Frame_Resource_Request* request)
1202 evas_object_smart_callback_call(ewkFrame, "resource,request,new", (void*)request);
1207 * Reports that first navigation occurred
1209 * @param ewkFrame Frame.
1211 * Emits signal: "navigation,first"
1213 void ewk_frame_did_perform_first_navigation(Evas_Object* ewkFrame)
1215 evas_object_smart_callback_call(ewkFrame, "navigation,first", 0);
1220 * Reports frame will be saved to current state
1222 * @param ewkFrame Frame.
1223 * @param item History item to save details to.
1225 * Emits signal: "state,save"
1227 void ewk_frame_view_state_save(Evas_Object* ewkFrame, WebCore::HistoryItem* item)
1229 evas_object_smart_callback_call(ewkFrame, "state,save", 0);
1234 * Reports the frame started loading something.
1236 * Emits signal: "load,started" with no parameters.
1238 void ewk_frame_load_started(Evas_Object* ewkFrame)
1240 Evas_Object* mainFrame;
1241 DBG("ewkFrame=%p", ewkFrame);
1242 evas_object_smart_callback_call(ewkFrame, "load,started", 0);
1243 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1244 ewk_view_load_started(smartData->view);
1246 mainFrame = ewk_view_frame_main_get(smartData->view);
1247 if (mainFrame == ewkFrame)
1248 ewk_view_frame_main_load_started(smartData->view);
1253 * Reports the frame started provisional load.
1255 * @param ewkFrame Frame.
1257 * Emits signal: "load,provisional" with no parameters.
1259 void ewk_frame_load_provisional(Evas_Object* ewkFrame)
1261 evas_object_smart_callback_call(ewkFrame, "load,provisional", 0);
1266 * Reports the frame finished first layout.
1268 * @param ewkFrame Frame.
1270 * Emits signal: "load,firstlayout,finished" with no parameters.
1272 void ewk_frame_load_firstlayout_finished(Evas_Object* ewkFrame)
1274 evas_object_smart_callback_call(ewkFrame, "load,firstlayout,finished", 0);
1279 * Reports the frame finished first non empty layout.
1281 * @param ewkFrame Frame.
1283 * Emits signal: "load,nonemptylayout,finished" with no parameters.
1285 void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object* ewkFrame)
1287 evas_object_smart_callback_call(ewkFrame, "load,nonemptylayout,finished", 0);
1292 * Reports the loading of a document has finished on frame.
1294 * @param ewkFrame Frame.
1296 * Emits signal: "load,document,finished" with no parameters.
1298 void ewk_frame_load_document_finished(Evas_Object* ewkFrame)
1300 evas_object_smart_callback_call(ewkFrame, "load,document,finished", 0);
1301 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd);
1302 ewk_view_load_document_finished(sd->view, ewkFrame);
1307 * Reports load finished, optionally with error information.
1309 * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error
1310 * if any error, or @c NULL if successful load.
1312 * @note there should notbe any error stuff here, but trying to be
1313 * compatible with previous WebKit.
1315 void ewk_frame_load_finished(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, Eina_Bool isCancellation, const char* errorDescription, const char* failingUrl)
1317 Ewk_Frame_Load_Error buffer, *error;
1319 DBG("ewkFrame=%p, success.", ewkFrame);
1322 DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
1323 ewkFrame, errorDomain, errorCode, isCancellation,
1324 errorDescription, failingUrl);
1326 buffer.domain = errorDomain;
1327 buffer.code = errorCode;
1328 buffer.is_cancellation = isCancellation;
1329 buffer.description = errorDescription;
1330 buffer.failing_url = failingUrl;
1331 buffer.frame = ewkFrame;
1334 evas_object_smart_callback_call(ewkFrame, "load,finished", error);
1335 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1336 ewk_view_load_finished(smartData->view, error);
1341 * Reports load failed with error information.
1343 * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
1345 void ewk_frame_load_error(Evas_Object* ewkFrame, const char* errorDomain, int errorCode, Eina_Bool isCancellation, const char* errorDescription, const char* failingUrl)
1347 Ewk_Frame_Load_Error error;
1349 DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
1350 ewkFrame, errorDomain, errorCode, isCancellation,
1351 errorDescription, failingUrl);
1353 EINA_SAFETY_ON_NULL_RETURN(errorDomain);
1355 error.code = errorCode;
1356 error.is_cancellation = isCancellation;
1357 error.domain = errorDomain;
1358 error.description = errorDescription;
1359 error.failing_url = failingUrl;
1360 error.frame = ewkFrame;
1361 evas_object_smart_callback_call(ewkFrame, "load,error", &error);
1362 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd);
1363 ewk_view_load_error(sd->view, &error);
1368 * Reports load progress changed.
1370 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
1372 void ewk_frame_load_progress_changed(Evas_Object* ewkFrame)
1374 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1375 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
1377 // TODO: this is per page, there should be a way to have per-frame.
1378 double progress = smartData->frame->page()->progress()->estimatedProgress();
1380 DBG("ewkFrame=%p (p=%0.3f)", ewkFrame, progress);
1382 evas_object_smart_callback_call(ewkFrame, "load,progress", &progress);
1383 ewk_view_load_progress_changed(smartData->view);
1390 * Reports contents size changed.
1392 void ewk_frame_contents_size_changed(Evas_Object* ewkFrame, Evas_Coord width, Evas_Coord height)
1394 Evas_Coord size[2] = {width, height};
1395 evas_object_smart_callback_call(ewkFrame, "contents,size,changed", size);
1401 * Reports title changed.
1403 void ewk_frame_title_set(Evas_Object* ewkFrame, const char* title)
1405 DBG("ewkFrame=%p, title=%s", ewkFrame, title ? title : "(null)");
1406 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd);
1407 if (!eina_stringshare_replace(&sd->title, title))
1409 evas_object_smart_callback_call(ewkFrame, "title,changed", (void*)sd->title);
1417 void ewk_frame_view_create_for_view(Evas_Object* ewkFrame, Evas_Object* view)
1419 DBG("ewkFrame=%p, view=%p", ewkFrame, view);
1420 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1421 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
1422 Evas_Coord width, height;
1424 evas_object_geometry_get(view, 0, 0, &width, &height);
1426 WebCore::IntSize size(width, height);
1427 int red, green, blue, alpha;
1428 WebCore::Color background;
1430 ewk_view_bg_color_get(view, &red, &green, &blue, &alpha);
1432 background = WebCore::Color(0, 0, 0, 0);
1433 else if (alpha == 255)
1434 background = WebCore::Color(red, green, blue, alpha);
1436 background = WebCore::Color(red * 255 / alpha, green * 255 / alpha, blue * 255 / alpha, alpha);
1438 smartData->frame->createView(size, background, !alpha, WebCore::IntSize(), false);
1439 if (!smartData->frame->view())
1442 const char* theme = ewk_view_theme_get(view);
1443 smartData->frame->view()->setEdjeTheme(theme);
1444 smartData->frame->view()->setEvasObject(ewkFrame);
1447 ssize_t ewk_frame_source_get(const Evas_Object* ewkFrame, char** frameSource)
1449 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, -1);
1450 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, -1);
1451 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), -1);
1452 EINA_SAFETY_ON_NULL_RETURN_VAL(frameSource, -1);
1455 *frameSource = 0; // Saves 0 to pointer until it's not allocated.
1457 if (!smartData->frame->document()->isHTMLDocument()) {
1458 // FIXME: Support others documents.
1459 WRN("Only HTML documents are supported");
1463 // Look for <html> tag. If it exists, the node contatins all document's source.
1464 WebCore::Node* documentNode = smartData->frame->document()->documentElement();
1466 for (WebCore::Node* node = documentNode->firstChild(); node; node = node->parentElement()) {
1467 if (node->hasTagName(WebCore::HTMLNames::htmlTag)) {
1468 WebCore::HTMLElement* element = static_cast<WebCore::HTMLElement*>(node);
1470 source = element->outerHTML();
1475 // Try to get <head> and <body> tags if <html> tag was not found.
1476 if (source.isEmpty()) {
1477 if (smartData->frame->document()->head())
1478 source = smartData->frame->document()->head()->outerHTML();
1480 if (smartData->frame->document()->body())
1481 source += smartData->frame->document()->body()->outerHTML();
1484 size_t sourceLength = strlen(source.utf8().data());
1485 *frameSource = static_cast<char*>(malloc(sourceLength + 1));
1486 if (!*frameSource) {
1487 CRITICAL("Could not allocate memory.");
1491 strncpy(*frameSource, source.utf8().data(), sourceLength);
1492 (*frameSource)[sourceLength] = '\0';
1494 return sourceLength;
1497 Eina_List* ewk_frame_resources_location_get(const Evas_Object* ewkFrame)
1499 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1500 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
1501 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame->document(), 0);
1503 Eina_List* listOfImagesLocation = 0;
1505 // Get src attibute of images and saves them to the Eina_List.
1506 RefPtr<WebCore::HTMLCollection> images = smartData->frame->document()->images();
1507 for (size_t index = 0; index < images->length(); ++index) {
1508 WebCore::HTMLImageElement* imageElement = static_cast<WebCore::HTMLImageElement*>(images->item(index));
1509 if (!imageElement || imageElement->src().isNull() || imageElement->src().isEmpty())
1512 WTF::String imageLocation = WebCore::decodeURLEscapeSequences(imageElement->src().string());
1513 // Look for duplicated location.
1514 Eina_List* listIterator = 0;
1516 Eina_Bool found = EINA_FALSE;
1517 EINA_LIST_FOREACH(listOfImagesLocation, listIterator, data)
1518 if (found = !strcmp(static_cast<char*>(data), imageLocation.utf8().data()))
1523 char* imageLocationCopy = strdup(imageLocation.utf8().data());
1524 if (!imageLocationCopy)
1525 goto out_of_memory_handler;
1526 listOfImagesLocation = eina_list_append(listOfImagesLocation, imageLocationCopy);
1527 if (eina_error_get())
1528 goto out_of_memory_handler;
1530 // FIXME: Get URL others resources (plugins, css, media files).
1531 return listOfImagesLocation;
1533 out_of_memory_handler:
1534 CRITICAL("Could not allocate memory.");
1536 EINA_LIST_FREE(listOfImagesLocation, data)
1541 char* ewk_frame_plain_text_get(const Evas_Object* ewkFrame)
1543 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData, 0);
1544 EINA_SAFETY_ON_NULL_RETURN_VAL(smartData->frame, 0);
1546 if (!smartData->frame->document())
1549 WebCore::Element* documentElement = smartData->frame->document()->documentElement();
1551 if (!documentElement)
1554 return strdup(documentElement->innerText().utf8().data());
1559 * Reports uri changed and swap internal string reference.
1561 * Emits signal: "uri,changed" with new uri as parameter.
1563 Eina_Bool ewk_frame_uri_changed(Evas_Object* ewkFrame)
1565 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, EINA_FALSE);
1566 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
1567 WTF::CString uri(sd->frame->document()->url().string().utf8());
1569 INF("uri=%s", uri.data());
1575 eina_stringshare_replace(&sd->uri, uri.data());
1576 evas_object_smart_callback_call(ewkFrame, "uri,changed", (void*)sd->uri);
1583 * Forces layout for frame.
1585 void ewk_frame_force_layout(Evas_Object* ewkFrame)
1587 DBG("ewkFrame=%p", ewkFrame);
1588 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, smartData);
1589 EINA_SAFETY_ON_NULL_RETURN(smartData->frame);
1590 WebCore::FrameView* view = smartData->frame->view();
1592 view->forceLayout(true);
1600 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)
1607 * Reports that editor client selection was changed.
1609 * @param ewkFrame Frame
1611 * Emits signal: "editorclientselection,changed" with no parameters.
1613 void ewk_frame_editor_client_selection_changed(Evas_Object* ewkFrame)
1615 evas_object_smart_callback_call(ewkFrame, "editorclient,selection,changed", 0);
1616 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd);
1617 ewk_view_editor_client_selection_changed(sd->view);
1622 * Reports that editor client's contents were changed.
1626 * Emits signal: "editorclient,contents,changed" with no parameters.
1628 void ewk_frame_editor_client_contents_changed(Evas_Object* ewkFrame)
1630 evas_object_smart_callback_call(ewkFrame, "editorclient,contents,changed", 0);
1631 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd);
1632 ewk_view_editor_client_contents_changed(sd->view);
1635 namespace EWKPrivate {
1637 WebCore::Frame *coreFrame(const Evas_Object *ewkFrame)
1639 EWK_FRAME_SD_GET_OR_RETURN(ewkFrame, sd, 0);
1643 Evas_Object* kitFrame(const WebCore::Frame* coreFrame)
1648 WebCore::FrameLoaderClientEfl* frameLoaderClient = _ewk_frame_loader_efl_get(coreFrame);
1649 if (!frameLoaderClient)
1652 return frameLoaderClient->webFrame();
1655 } // namespace EWKPrivate