2 * Copyright (C) 2012 Samsung Electronics
3 * Copyright (C) 2012 Intel Corporation. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "url_utils.h"
23 #include <Ecore_Evas.h>
24 #include <Ecore_Getopt.h>
27 #include <Elementary.h>
30 static const char DEFAULT_URL[] = "http://www.google.com/";
31 static const char APP_NAME[] = "EFL MiniBrowser";
32 static const int TOOL_BAR_ICON_SIZE = 24;
33 static const int TOOL_BAR_BUTTON_SIZE = 32;
34 static const int SEARCH_FIELD_SIZE = 200;
35 static const int SEARCH_BUTTON_SIZE = 25;
36 static const int MAX_SEARCH_COUNT = 100;
37 static const int DEFAULT_SEARCH_FLAGS = EWK_FIND_OPTIONS_SHOW_HIGHLIGHT | EWK_FIND_OPTIONS_CASE_INSENSITIVE | EWK_FIND_OPTIONS_WRAP_AROUND;
38 static const double TOOLTIP_DELAY_SECONDS = 1.0;
40 #define info(format, args...) \
43 printf(format"\n", ##args); \
46 static int verbose = 1;
47 static Eina_List *windows = NULL;
48 static char *evas_engine_name = NULL;
49 static char *user_agent_string = NULL;
50 static Eina_Bool encoding_detector_enabled = EINA_FALSE;
51 static Eina_Bool frame_flattening_enabled = EINA_FALSE;
52 static Eina_Bool local_storage_enabled = EINA_TRUE;
53 static Eina_Bool fullscreen_enabled = EINA_FALSE;
54 static Eina_Bool spell_checking_enabled = EINA_FALSE;
55 static Eina_Bool touch_events_enabled = EINA_FALSE;
56 static Eina_Bool fixed_layout_enabled = EINA_FALSE;
57 static int window_width = 800;
58 static int window_height = 600;
59 /* Default value of device_pixel_ratio is '0' so that we don't set custom device
60 * scale factor unless it's required by the User. */
61 static double device_pixel_ratio = 0;
62 static Eina_Bool legacy_behavior_enabled = EINA_FALSE;
64 #define DEFAULT_ZOOM_LEVEL 5 // Set default zoom level to 1.0 (index 5 on zoomLevels).
65 // The zoom values are chosen to be like in Mozilla Firefox 3.
66 const static float zoomLevels[] = {0.3, 0.5, 0.67, 0.8, 0.9, 1.0, 1.1, 1.2, 1.33, 1.5, 1.7, 2.0, 2.4, 3.0};
69 zoom_level_set(Evas_Object *webview, int level)
71 if (level < 0 || level >= sizeof(zoomLevels) / sizeof(float))
74 Evas_Coord ox, oy, mx, my, cx, cy;
75 evas_pointer_canvas_xy_get(evas_object_evas_get(webview), &mx, &my); // Get current mouse position on window.
76 evas_object_geometry_get(webview, &ox, &oy, NULL, NULL); // Get webview's position on window.
77 cx = mx - ox; // current x position = mouse x position - webview x position
78 cy = my - oy; // current y position = mouse y position - webview y position
80 Eina_Bool result = ewk_view_scale_set(webview, zoomLevels[level], cx, cy);
84 static Ewk_View_Smart_Class *miniBrowserViewSmartClass()
86 static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("MiniBrowser_View");
90 typedef struct _Tooltip_Information {
91 Ecore_Timer *show_timer;
95 } Tooltip_Information;
97 typedef struct _Color_Selector {
98 Ewk_Color_Picker *ewk_picker;
99 Evas_Object *elm_selector;
100 Evas_Object *elm_selector_window;
103 typedef struct _Browser_Window {
104 Evas_Object *elm_window;
105 Evas_Object *ewk_view;
106 Evas_Object *url_bar;
107 Evas_Object *back_button;
108 Evas_Object *forward_button;
110 Evas_Object *elm_menu;
111 Ewk_Popup_Menu *ewk_menu;
114 Evas_Object *search_bar;
115 Evas_Object *search_field;
116 Evas_Object *backward_button;
117 Evas_Object *forward_button;
119 int current_zoom_level;
120 Tooltip_Information tooltip;
121 Color_Selector color_selector;
123 Evas_Object *elm_menu;
124 Ewk_Context_Menu *ewk_menu;
128 typedef struct _File_Selector_Data {
129 Browser_Window* parent;
130 Evas_Object *elm_window;
131 Ewk_File_Chooser_Request *request;
132 } File_Selector_Data;
134 typedef struct _Auth_Data {
136 Ewk_Auth_Request *request;
137 Evas_Object *username_entry;
138 Evas_Object *password_entry;
141 static const Ecore_Getopt options = {
143 "%prog [options] [url]",
145 "(C)2012 Samsung Electronics\n (C)2012 Intel Corporation\n",
147 "Test Web Browser using the Enlightenment Foundation Libraries (EFL) port of WebKit2",
149 ECORE_GETOPT_STORE_STR
150 ('e', "engine", "Ecore-evas engine to use."),
151 ECORE_GETOPT_STORE_STR
152 ('s', "window-size", "Window size in following format (width)x(height)."),
153 ECORE_GETOPT_STORE_STR
154 ('u', "user-agent", "User agent to set."),
155 ECORE_GETOPT_STORE_DOUBLE
156 ('r', "device-pixel-ratio", "Ratio between the CSS units and device pixels."),
157 ECORE_GETOPT_CALLBACK_NOARGS
158 ('E', "list-engines", "List ecore-evas engines.",
159 ecore_getopt_callback_ecore_evas_list_engines, NULL),
160 ECORE_GETOPT_STORE_DEF_BOOL
161 ('c', "encoding-detector", "Enable/disable encoding detector.", EINA_FALSE),
162 ECORE_GETOPT_STORE_DEF_BOOL
163 ('f', "flattening", "Enable/disable frame flattening.", EINA_FALSE),
164 ECORE_GETOPT_STORE_DEF_BOOL
165 ('l', "local-storage", "Enable/disable HTML5 local storage.", EINA_TRUE),
166 ECORE_GETOPT_STORE_DEF_BOOL
167 ('F', "full-screen", "Start in full-screen.", EINA_FALSE),
168 ECORE_GETOPT_STORE_DEF_BOOL
169 ('t', "text-checking", "Enable/disable text spell checking.", EINA_FALSE),
170 ECORE_GETOPT_STORE_DEF_BOOL
171 ('T', "touch-events", "Enable/disable touch events.", EINA_FALSE),
172 ECORE_GETOPT_STORE_DEF_BOOL
173 ('L', "fixed-layout", "Enable/disable fixed layout.", EINA_FALSE),
174 ECORE_GETOPT_STORE_DEF_STR
175 ('p', "policy-cookies", "Cookies policy:\n always - always accept,\n never - never accept,\n no-third-party - don't accept third-party cookies.", "no-third-party"),
178 ECORE_GETOPT_COPYRIGHT
182 ECORE_GETOPT_SENTINEL
186 static Eina_Stringshare *show_file_entry_dialog(Browser_Window *window, const char *label_tag, const char *default_text);
187 static Browser_Window *window_create(Evas_Object* opener, int width, int height);
189 static Browser_Window *window_find_with_elm_window(Evas_Object *elm_window)
197 EINA_LIST_FOREACH(windows, l, data) {
198 Browser_Window *window = (Browser_Window *)data;
199 if (window->elm_window == elm_window)
205 static Browser_Window *window_find_with_ewk_view(Evas_Object *ewk_view)
213 EINA_LIST_FOREACH(windows, l, data) {
214 Browser_Window *window = (Browser_Window *)data;
215 if (window->ewk_view == ewk_view)
222 on_tooltip_show(void *user_data)
224 Browser_Window *window = (Browser_Window *)user_data;
226 window->tooltip.show_timer = NULL;
227 elm_object_tooltip_show(window->elm_window);
228 window->tooltip.shown = EINA_TRUE;
229 return ECORE_CALLBACK_CANCEL;
233 window_tooltip_hide(Browser_Window *window)
235 if (window->tooltip.show_timer) {
236 ecore_timer_del(window->tooltip.show_timer);
237 window->tooltip.show_timer = NULL;
240 if (window->tooltip.shown) {
241 elm_object_tooltip_hide(window->elm_window);
242 window->tooltip.shown = EINA_FALSE;
247 window_tooltip_update(Browser_Window *window)
249 window_tooltip_hide(window);
251 if (window->tooltip.activated && window->tooltip.text_set)
252 window->tooltip.show_timer = ecore_timer_add(TOOLTIP_DELAY_SECONDS, on_tooltip_show, window);
256 on_mouse_in(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
258 Browser_Window *window = (Browser_Window *)user_data;
260 window->tooltip.activated = EINA_TRUE;
261 window_tooltip_update(window);
265 on_mouse_move(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
267 window_tooltip_update((Browser_Window *)user_data);
271 on_mouse_out(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
273 Browser_Window *window = (Browser_Window *)user_data;
275 window->tooltip.activated = EINA_FALSE;
276 window_tooltip_update(window);
280 on_window_resize(void *user_data, Evas *e, Evas_Object *elm_window, void *event_info)
282 Browser_Window *window = (Browser_Window *)user_data;
285 info("ERROR: window is NULL.");
289 if (window->context_menu.ewk_menu)
290 ewk_context_menu_hide(window->context_menu.ewk_menu);
291 if (window->popup.ewk_menu)
292 ewk_popup_menu_close(window->popup.ewk_menu);
293 if (window->popup.elm_menu)
294 elm_menu_close(window->popup.elm_menu);
297 static void window_free(Browser_Window *window)
299 evas_object_event_callback_del(window->ewk_view, EVAS_CALLBACK_MOUSE_IN, on_mouse_in);
300 evas_object_event_callback_del(window->ewk_view, EVAS_CALLBACK_MOUSE_OUT, on_mouse_out);
301 evas_object_event_callback_del(window->ewk_view, EVAS_CALLBACK_MOUSE_MOVE, on_mouse_move);
303 evas_object_event_callback_del(window->elm_window, EVAS_CALLBACK_RESIZE, on_window_resize);
305 evas_object_del(window->ewk_view);
306 /* The elm_win will take care of freeing its children */
307 evas_object_del(window->elm_window);
309 if (window->tooltip.show_timer)
310 ecore_timer_del(window->tooltip.show_timer);
312 if (window->color_selector.elm_selector_window)
313 evas_object_del(window->color_selector.elm_selector_window);
318 static void window_close(Browser_Window *window)
320 windows = eina_list_remove(windows, window);
328 search_box_show(Browser_Window *window)
330 evas_object_size_hint_min_set(window->search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
332 evas_object_show(window->search.search_bar);
333 evas_object_show(window->search.search_field);
334 evas_object_show(window->search.backward_button);
335 evas_object_show(window->search.forward_button);
337 /* Grab focus from the view */
338 evas_object_focus_set(window->ewk_view, EINA_FALSE);
339 elm_object_focus_set(window->search.search_field, EINA_TRUE);
343 search_box_hide(Browser_Window *window)
345 ewk_view_text_find_highlight_clear(window->ewk_view);
347 evas_object_size_hint_min_set(window->search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, 0);
348 evas_object_hide(window->search.search_bar);
349 evas_object_hide(window->search.search_field);
350 evas_object_hide(window->search.backward_button);
351 evas_object_hide(window->search.forward_button);
353 /* Give focus back to the view */
354 elm_object_focus_set(window->search.search_field, EINA_FALSE);
355 evas_object_focus_set(window->ewk_view, EINA_TRUE);
358 static void save_page_contents_callback(Ewk_Page_Contents_Type type, const char *data, void *user_data)
361 Eina_Stringshare *fileName = (Eina_Stringshare *)user_data;
363 if (!eina_str_has_extension(fileName, ".mht")) {
364 Eina_Strbuf *fileNameWithMht = eina_strbuf_new();
365 eina_strbuf_append_printf(fileNameWithMht, "%s.mht", fileName);
366 ef = eet_open(eina_strbuf_string_get(fileNameWithMht), EET_FILE_MODE_WRITE);
367 info("Saving file to: %s", eina_strbuf_string_get(fileNameWithMht));
368 eina_strbuf_free(fileNameWithMht);
370 ef = eet_open(fileName, EET_FILE_MODE_WRITE);
371 info("Saving file to: %s", fileName);
375 info("ERROR: Could not create File");
379 eet_write(ef, "MHTML data", data, strlen(data), 0 /* compress */);
381 info("SUCCESS: saved.");
383 eina_stringshare_del(fileName);
387 on_key_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
389 Browser_Window *window = (Browser_Window *)user_data;
390 Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
392 static const char *encodings[] = {
397 static int currentEncoding = -1;
398 const Evas_Modifier *mod = evas_key_modifier_get(e);
399 Eina_Bool ctrlPressed = evas_key_modifier_is_set(mod, "Control");
400 Eina_Bool altPressed = evas_key_modifier_is_set(mod, "Alt");
402 if (!strcmp(ev->key, "Left") && altPressed) {
403 info("Back (Alt+Left) was pressed");
404 if (!ewk_view_back(ewk_view))
405 info("Back ignored: No back history");
406 } else if (!strcmp(ev->key, "Right") && altPressed) {
407 info("Forward (Alt+Right) was pressed");
408 if (!ewk_view_forward(ewk_view))
409 info("Forward ignored: No forward history");
410 } else if (!strcmp(ev->key, "Home") && altPressed) {
411 info("Home (Alt+Home) was pressed");
412 ewk_view_url_set(window->ewk_view, DEFAULT_URL);
413 } else if (!strcmp(ev->key, "F3")) {
414 currentEncoding = (currentEncoding + 1) % (sizeof(encodings) / sizeof(encodings[0]));
415 info("Set encoding (F3) pressed. New encoding to %s", encodings[currentEncoding]);
416 ewk_view_custom_encoding_set(ewk_view, encodings[currentEncoding]);
417 } else if (!strcmp(ev->key, "F5")) {
418 info("Reload (F5) was pressed, reloading.");
419 ewk_view_reload(ewk_view);
420 } else if (!strcmp(ev->key, "F6")) {
421 info("Stop (F6) was pressed, stop loading.");
422 ewk_view_stop(ewk_view);
423 } else if (!strcmp(ev->key, "F7")) {
424 Ewk_Pagination_Mode mode = ewk_view_pagination_mode_get(ewk_view);
425 mode = (++mode) % (EWK_PAGINATION_MODE_BOTTOM_TO_TOP + 1);
426 if (ewk_view_pagination_mode_set(ewk_view, mode))
427 info("Change Pagination Mode (F7) was pressed, changed to: %d", mode);
429 info("Change Pagination Mode (F7) was pressed, but NOT changed!");
430 } else if (!strcmp(ev->key, "F11")) {
431 info("Fullscreen (F11) was pressed, toggling window/fullscreen.");
432 elm_win_fullscreen_set(window->elm_window, !elm_win_fullscreen_get(window->elm_window));
433 } else if (!strcmp(ev->key, "n") && ctrlPressed) {
434 info("Create new window (Ctrl+n) was pressed.");
435 Browser_Window *window = window_create(NULL, 0, 0);
436 ewk_view_url_set(window->ewk_view, DEFAULT_URL);
437 // 0 equals default width and height.
438 windows = eina_list_append(windows, window);
439 } else if (!strcmp(ev->key, "i") && ctrlPressed) {
440 info("Show Inspector (Ctrl+i) was pressed.");
441 ewk_view_inspector_show(ewk_view);
442 } else if (!strcmp(ev->key, "f") && ctrlPressed) {
443 info("Show Search Box (Ctrl+f) was pressed.");
444 search_box_show(window);
445 } else if (!strcmp(ev->key, "Escape")) {
446 if (evas_object_visible_get(window->search.search_bar))
447 search_box_hide(window);
448 else if (elm_win_fullscreen_get(window->elm_window))
449 ewk_view_fullscreen_exit(ewk_view);
450 } else if (ctrlPressed && (!strcmp(ev->key, "minus") || !strcmp(ev->key, "KP_Subtract"))) {
451 if (zoom_level_set(ewk_view, window->current_zoom_level - 1))
452 window->current_zoom_level--;
453 info("Zoom out (Ctrl + '-') was pressed, zoom level became %.2f", zoomLevels[window->current_zoom_level]);
454 } else if (ctrlPressed && (!strcmp(ev->key, "equal") || !strcmp(ev->key, "KP_Add"))) {
455 if (zoom_level_set(ewk_view, window->current_zoom_level + 1))
456 window->current_zoom_level++;
457 info("Zoom in (Ctrl + '+') was pressed, zoom level became %.2f", zoomLevels[window->current_zoom_level]);
458 } else if (ctrlPressed && !strcmp(ev->key, "0")) {
459 if (zoom_level_set(ewk_view, DEFAULT_ZOOM_LEVEL))
460 window->current_zoom_level = DEFAULT_ZOOM_LEVEL;
461 info("Zoom to default (Ctrl + '0') was pressed, zoom level became %.2f", zoomLevels[window->current_zoom_level]);
462 } else if (ctrlPressed && !strcmp(ev->key, "s")) {
463 Eina_Strbuf *default_file = eina_strbuf_new();
464 const char *home_path = getenv("HOME");
465 const char *title = ewk_view_title_get(window->ewk_view);
466 eina_strbuf_append_printf(default_file, "%s/%s.mht", home_path ? home_path : "/home", title ? title : "title");
467 info("Pressed (CTRL + S) : Saving Current Page.");
468 Eina_Stringshare *save_file_name = show_file_entry_dialog(window, "SAVE", eina_strbuf_string_get(default_file));
471 ewk_view_page_contents_get(ewk_view, EWK_PAGE_CONTENTS_TYPE_MHTML, save_page_contents_callback, (void *)save_file_name);
472 eina_strbuf_free(default_file);
473 } else if (ctrlPressed && !strcmp(ev->key, "l")) {
474 const char *home_path = getenv("HOME");
475 Eina_Stringshare *open_file_name = show_file_entry_dialog(window, "LOAD", home_path ? home_path : "/home");
478 Eina_Strbuf *uri_path = eina_strbuf_new();
479 eina_strbuf_append_printf(uri_path, "file://%s", open_file_name);
480 info("pressed (CTRL + L) : Loading Page %s", eina_strbuf_string_get(uri_path));
481 ewk_view_url_set(ewk_view, eina_strbuf_string_get(uri_path));
482 eina_strbuf_free(uri_path);
483 eina_stringshare_del(open_file_name);
488 view_focus_set(Browser_Window *window, Eina_Bool focus)
490 /* We steal focus away from elm's focus model and start to do things
491 * manually here, so elm now has no clue what's up. Tell elm that its
492 * toplevel widget is to be unfocused so elm gives up the focus */
493 elm_object_focus_set(elm_object_top_widget_get(window->elm_window), EINA_FALSE);
494 evas_object_focus_set(window->ewk_view, focus);
498 on_mouse_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info)
500 Browser_Window *window = (Browser_Window *)user_data;
501 Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
503 /* Clear selection from the URL bar */
504 elm_entry_select_none(window->url_bar);
507 view_focus_set(window, EINA_TRUE);
508 else if (ev->button == 2)
509 view_focus_set(window, !evas_object_focus_get(ewk_view));
513 title_set(Evas_Object *elm_window, const char *title, int progress)
517 if (!title || !*title) {
518 elm_win_title_set(elm_window, APP_NAME);
522 buffer = eina_strbuf_new();
524 eina_strbuf_append_printf(buffer, "%s (%d%%) - %s", title, progress, APP_NAME);
526 eina_strbuf_append_printf(buffer, "%s - %s", title, APP_NAME);
528 elm_win_title_set(elm_window, eina_strbuf_string_get(buffer));
529 eina_strbuf_free(buffer);
533 on_title_changed(void *user_data, Evas_Object *ewk_view, void *event_info)
535 Browser_Window *window = (Browser_Window *)user_data;
536 const char *title = (const char *)event_info;
538 title_set(window->elm_window, title, 100);
542 on_url_changed(void *user_data, Evas_Object *ewk_view, void *event_info)
544 Browser_Window *window = (Browser_Window *)user_data;
546 char *url = elm_entry_utf8_to_markup(ewk_view_url_get(window->ewk_view));
547 elm_entry_entry_set(window->url_bar, url);
551 search_box_hide(window);
555 on_back_forward_list_changed(void *user_data, Evas_Object *ewk_view, void *event_info)
557 Browser_Window *window = (Browser_Window *)user_data;
559 /* Update navigation buttons state */
560 elm_object_disabled_set(window->back_button, !ewk_view_back_possible(ewk_view));
561 elm_object_disabled_set(window->forward_button, !ewk_view_forward_possible(ewk_view));
565 on_progress(void *user_data, Evas_Object *ewk_view, void *event_info)
567 Browser_Window *window = (Browser_Window *)user_data;
568 double progress = *(double *)event_info;
570 title_set(window->elm_window, ewk_view_title_get(window->ewk_view), progress * 100);
574 on_error(void *user_data, Evas_Object *ewk_view, void *event_info)
577 const Ewk_Error *error = (const Ewk_Error *)event_info;
579 /* This is a cancellation, do not display the error page */
580 if (ewk_error_cancellation_get(error))
583 buffer = eina_strbuf_new();
584 eina_strbuf_append_printf(buffer, "<html><body><div style=\"color:#ff0000\">ERROR!</div><br><div>Code: %d<br>Description: %s<br>URL: %s</div></body</html>",
585 ewk_error_code_get(error), ewk_error_description_get(error), ewk_error_url_get(error));
587 ewk_view_html_string_load(ewk_view, eina_strbuf_string_get(buffer), 0, ewk_error_url_get(error));
588 eina_strbuf_free(buffer);
592 on_download_request(void *user_data, Evas_Object *ewk_view, void *event_info)
594 Ewk_Download_Job *download = (Ewk_Download_Job *)event_info;
596 // FIXME: The destination folder should be selected by the user but we set it to '/tmp' for now.
597 Eina_Strbuf *destination_path = eina_strbuf_new();
599 const char *suggested_name = ewk_download_job_suggested_filename_get(download);
600 if (suggested_name && *suggested_name)
601 eina_strbuf_append_printf(destination_path, "/tmp/%s", suggested_name);
603 // Generate a unique file name since no name was suggested.
604 char unique_path[] = "/tmp/downloaded-file.XXXXXX";
605 if (mkstemp(unique_path) == -1) {
606 info("ERROR: Could not generate a unique file name.");
609 eina_strbuf_append(destination_path, unique_path);
612 ewk_download_job_destination_set(download, eina_strbuf_string_get(destination_path));
613 info("Downloading: %s", eina_strbuf_string_get(destination_path));
614 eina_strbuf_free(destination_path);
617 static void on_filepicker_parent_deletion(void *user_data, Evas *evas, Evas_Object *elm_window, void *event);
619 static void close_file_picker(File_Selector_Data *fs_data)
621 evas_object_event_callback_del(fs_data->parent->elm_window, EVAS_CALLBACK_DEL, on_filepicker_parent_deletion);
622 evas_object_del(fs_data->elm_window);
623 ewk_object_unref(fs_data->request);
628 on_filepicker_parent_deletion(void *user_data, Evas *evas, Evas_Object *elm_window, void *event)
630 close_file_picker((File_Selector_Data *)user_data);
634 on_filepicker_deletion(void *user_data, Evas_Object *elm_window, void *event_info)
636 close_file_picker((File_Selector_Data *)user_data);
640 on_fileselector_done(void *user_data, Evas_Object *file_selector, void *event_info)
642 File_Selector_Data *fs_data = (File_Selector_Data *)user_data;
644 const char *selected = (const char *)event_info;
645 if (selected && *selected)
646 ewk_file_chooser_request_file_choose(fs_data->request, selected);
648 close_file_picker(fs_data);
652 on_file_chooser_request(void *user_data, Evas_Object *ewk_view, void *event_info)
655 Browser_Window *window = (Browser_Window *)user_data;
656 Ewk_File_Chooser_Request *request = (Ewk_File_Chooser_Request *)event_info;
658 // Show basic file picker which does not currently support multiple files
659 // or MIME type filtering.
660 Evas_Object *elm_window = elm_win_add(window->elm_window, "file-picker-window", ELM_WIN_DIALOG_BASIC);
661 elm_win_title_set(elm_window, "File picker");
662 elm_win_modal_set(elm_window, EINA_TRUE);
664 bg = elm_bg_add(elm_window);
665 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
666 elm_win_resize_object_add(elm_window, bg);
667 evas_object_show(bg);
669 File_Selector_Data *fs_data = (File_Selector_Data *)malloc(sizeof(File_Selector_Data));
670 fs_data->parent = window;
671 fs_data->elm_window = elm_window;
672 fs_data->request = ewk_object_ref(request);
673 evas_object_smart_callback_add(elm_window, "delete,request", on_filepicker_deletion, fs_data);
674 evas_object_event_callback_add(window->elm_window, EVAS_CALLBACK_DEL, on_filepicker_parent_deletion, fs_data);
676 Evas_Object *file_selector = elm_fileselector_add(elm_window);
677 const char *home_path = getenv("HOME");
678 elm_fileselector_path_set(file_selector, home_path ? home_path : "/home");
679 evas_object_size_hint_weight_set(file_selector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
680 elm_win_resize_object_add(elm_window, file_selector);
681 evas_object_show(file_selector);
683 evas_object_smart_callback_add(file_selector, "done", on_fileselector_done, fs_data);
685 evas_object_resize(elm_window, 400, 400);
686 elm_win_center(elm_window, EINA_TRUE, EINA_TRUE);
687 evas_object_show(elm_window);
691 on_download_finished(void *user_data, Evas_Object *ewk_view, void *event_info)
693 Ewk_Download_Job *download = (Ewk_Download_Job *)event_info;
694 info("Download finished: %s", ewk_download_job_destination_get(download));
698 on_download_failed(void *user_data, Evas_Object *ewk_view, void *event_info)
700 info("Download failed!");
704 on_color_changed(void *data, Evas_Object *obj, void *event_info)
708 elm_colorselector_color_get(obj, &r, &g, &b, &a);
709 evas_object_color_set(data, r, g, b, a);
713 on_color_item_selected(void *data, Evas_Object *obj, void *event_info)
716 Elm_Object_Item *color_item = (Elm_Object_Item *)event_info;
718 elm_colorselector_palette_item_color_get(color_item, &r, &g, &b, &a);
719 evas_object_color_set(data, r, g, b, a);
723 on_color_picker_ok_clicked(void *data, Evas_Object *obj, void *event_info)
726 Color_Selector *color_selector = (Color_Selector *)data;
728 elm_colorselector_color_get(color_selector->elm_selector, &r, &g, &b, &a);
729 ewk_color_picker_color_set(color_selector->ewk_picker, r, g, b, a);
733 on_color_picker_cancel_clicked(void *data, Evas_Object *obj, void *event_info)
737 ewk_color_picker_color_get(data, &r, &g, &b, &a);
738 ewk_color_picker_color_set(data, r, g, b, a);
742 on_color_picker_dismiss(Ewk_View_Smart_Data *sd)
744 Browser_Window *window = window_find_with_ewk_view(sd->self);
746 evas_object_del(window->color_selector.elm_selector_window);
747 window->color_selector.elm_selector_window = NULL;
753 on_color_picker_request(Ewk_View_Smart_Data *sd, Ewk_Color_Picker *color_picker)
756 Evas_Object *background, *rect, *box, *button_box, *rect_frame, *cs_frame, *ok_button, *cancel_button;
758 Browser_Window *window = window_find_with_ewk_view(sd->self);
759 window->color_selector.elm_selector_window = elm_win_add(window->elm_window, "color selector", ELM_WIN_BASIC);
760 window->color_selector.ewk_picker = color_picker;
762 elm_win_title_set(window->color_selector.elm_selector_window, "Color selector");
764 /* Show color view */
765 background = elm_bg_add(window->color_selector.elm_selector_window);
766 evas_object_size_hint_weight_set(background, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
767 elm_win_resize_object_add(window->color_selector.elm_selector_window, background);
768 evas_object_show(background);
770 box = elm_box_add(window->color_selector.elm_selector_window);
771 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
772 elm_win_resize_object_add(window->color_selector.elm_selector_window, box);
773 evas_object_show(box);
775 rect_frame = elm_frame_add(window->color_selector.elm_selector_window);
776 evas_object_size_hint_weight_set(rect_frame, EVAS_HINT_EXPAND, 0.3);
777 evas_object_size_hint_align_set(rect_frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
778 elm_object_text_set(rect_frame, "Color View");
779 elm_box_pack_end(box, rect_frame);
780 evas_object_show(rect_frame);
782 rect = evas_object_rectangle_add(evas_object_evas_get(window->color_selector.elm_selector_window));
783 elm_object_content_set(rect_frame, rect);
784 ewk_color_picker_color_get(window->color_selector.ewk_picker, &r, &g, &b, &a);
785 evas_object_color_set(rect, r, g, b, a);
786 evas_object_show(rect);
788 /* Show color selector */
789 cs_frame = elm_frame_add(window->color_selector.elm_selector_window);
790 evas_object_size_hint_weight_set(cs_frame, EVAS_HINT_EXPAND, 0.7);
791 evas_object_size_hint_align_set(cs_frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
792 elm_object_text_set(cs_frame, "Color Selector");
793 elm_box_pack_end(box, cs_frame);
794 evas_object_show(cs_frame);
796 window->color_selector.elm_selector = elm_colorselector_add(window->color_selector.elm_selector_window);
797 elm_object_content_set(cs_frame, window->color_selector.elm_selector);
798 evas_object_show(window->color_selector.elm_selector);
800 /* OK, Cancel Buttons */
801 button_box = elm_box_add(window->color_selector.elm_selector_window);
802 elm_box_horizontal_set(button_box, EINA_TRUE);
803 evas_object_size_hint_min_set(button_box, 200, 50);
804 elm_box_pack_end(box, button_box);
805 evas_object_show(button_box);
807 ok_button = elm_button_add(window->color_selector.elm_selector_window);
808 elm_object_text_set(ok_button, "OK");
809 elm_box_pack_end(button_box, ok_button);
810 evas_object_show(ok_button);
812 cancel_button = elm_button_add(window->color_selector.elm_selector_window);
813 elm_object_text_set(cancel_button, "Cancel");
814 elm_box_pack_end(button_box, cancel_button);
815 evas_object_show(cancel_button);
817 evas_object_smart_callback_add(ok_button, "clicked", on_color_picker_ok_clicked, &(window->color_selector));
818 evas_object_smart_callback_add(cancel_button, "clicked", on_color_picker_cancel_clicked, window->color_selector.ewk_picker);
819 evas_object_smart_callback_add(window->color_selector.elm_selector_window, "delete,request", on_color_picker_cancel_clicked, window->color_selector.ewk_picker);
820 evas_object_smart_callback_add(window->color_selector.elm_selector, "changed", on_color_changed, rect);
821 evas_object_smart_callback_add(window->color_selector.elm_selector, "color,item,selected", on_color_item_selected, rect);
823 elm_win_center(window->color_selector.elm_selector_window, EINA_TRUE, EINA_TRUE);
824 evas_object_resize(window->color_selector.elm_selector_window, 350, 500);
825 evas_object_show(window->color_selector.elm_selector_window);
831 update_view_favicon(Browser_Window *window, Evas_Object *icon)
833 /* Remove previous icon from URL bar */
834 Evas_Object *old_icon = elm_object_part_content_unset(window->url_bar, "icon");
836 evas_object_unref(old_icon);
837 evas_object_del(old_icon);
840 /* Show new icon in URL bar */
842 /* Workaround for icon display bug:
843 * http://trac.enlightenment.org/e/ticket/1616 */
844 evas_object_size_hint_min_set(icon, 48, 24);
845 evas_object_image_filled_set(icon, EINA_FALSE);
846 evas_object_image_fill_set(icon, 24, 0, 24, 24);
847 elm_object_part_content_set(window->url_bar, "icon", icon);
848 evas_object_ref(icon);
853 on_view_favicon_changed(void *user_data, Evas_Object *ewk_view, void *event_info)
855 Browser_Window *window = (Browser_Window *)user_data;
857 Evas_Object* favicon = ewk_view_favicon_get(ewk_view);
858 update_view_favicon(window, favicon);
861 evas_object_unref(favicon);
865 quit(Eina_Bool success, const char *msg)
871 fputs(msg, (success) ? stdout : stderr);
880 on_url_bar_activated(void *user_data, Evas_Object *url_bar, void *event_info)
882 Browser_Window *window = (Browser_Window *)user_data;
884 const char *markup_url = elm_entry_entry_get(url_bar);
885 char *user_url = elm_entry_markup_to_utf8(markup_url);
886 char *url = url_from_user_input(user_url);
887 ewk_view_url_set(window->ewk_view, url);
892 /* Give focus back to the view */
893 view_focus_set(window, EINA_TRUE);
897 on_url_bar_clicked(void *user_data, Evas_Object *url_bar, void *event_info)
899 Browser_Window *window = (Browser_Window *)user_data;
901 /* Grab focus from the view */
902 evas_object_focus_set(window->ewk_view, EINA_FALSE);
903 elm_object_focus_set(url_bar, EINA_TRUE);
907 on_search_field_aborted(void *user_data, Evas_Object *search_field, void *event_info)
909 Browser_Window *window = (Browser_Window *)user_data;
910 search_box_hide(window);
912 /* Give focus back to the view */
913 view_focus_set(window, EINA_TRUE);
917 on_search_field_activated(void *user_data, Evas_Object *search_field, void *event_info)
919 Browser_Window *window = (Browser_Window *)user_data;
921 const char *markup_text = elm_entry_entry_get(search_field);
922 char *text = elm_entry_markup_to_utf8(markup_text);
923 ewk_view_text_find(window->ewk_view, text, DEFAULT_SEARCH_FLAGS, MAX_SEARCH_COUNT);
926 /* Grab focus from the view */
927 evas_object_focus_set(window->ewk_view, EINA_FALSE);
928 elm_object_focus_set(search_field, EINA_TRUE);
932 on_search_field_clicked(void *user_data, Evas_Object *search_field, void *event_info)
934 Browser_Window *window = (Browser_Window *)user_data;
936 /* Grab focus from the view */
937 evas_object_focus_set(window->ewk_view, EINA_FALSE);
938 elm_object_focus_set(search_field, EINA_TRUE);
942 on_back_button_clicked(void *user_data, Evas_Object *back_button, void *event_info)
944 Browser_Window *window = (Browser_Window *)user_data;
946 ewk_view_back(window->ewk_view);
947 /* Update back button state */
948 elm_object_disabled_set(back_button, !ewk_view_back_possible(window->ewk_view));
952 on_forward_button_clicked(void *user_data, Evas_Object *forward_button, void *event_info)
954 Browser_Window *window = (Browser_Window *)user_data;
956 ewk_view_forward(window->ewk_view);
957 /* Update forward button state */
958 elm_object_disabled_set(forward_button, !ewk_view_forward_possible(window->ewk_view));
962 on_search_backward_button_clicked(void *user_data, Evas_Object *search_backward_button, void *event_info)
964 Browser_Window *window = (Browser_Window *)user_data;
966 char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window->search.search_field));
967 ewk_view_text_find(window->ewk_view, text, DEFAULT_SEARCH_FLAGS | EWK_FIND_OPTIONS_BACKWARDS, MAX_SEARCH_COUNT);
972 on_search_forward_button_clicked(void *user_data, Evas_Object *search_forward_button, void *event_info)
974 Browser_Window *window = (Browser_Window *)user_data;
976 char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(window->search.search_field));
977 ewk_view_text_find(window->ewk_view, text, DEFAULT_SEARCH_FLAGS, MAX_SEARCH_COUNT);
982 on_refresh_button_clicked(void *user_data, Evas_Object *refresh_button, void *event_info)
984 Browser_Window *window = (Browser_Window *)user_data;
986 Evas *evas = evas_object_evas_get(refresh_button);
987 Eina_Bool ctrlPressed = evas_key_modifier_is_set(evas_key_modifier_get(evas), "Control");
989 info("Reloading and bypassing cache...");
990 ewk_view_reload_bypass_cache(window->ewk_view);
992 info("Reloading...");
993 ewk_view_reload(window->ewk_view);
998 quit_event_loop(void *user_data, Evas_Object *obj, void *event_info)
1000 ecore_main_loop_quit();
1004 on_ok_clicked(void *user_data, Evas_Object *obj, void *event_info)
1006 Eina_Bool *confirmed = (Eina_Bool *)user_data;
1007 *confirmed = EINA_TRUE;
1009 ecore_main_loop_quit();
1012 static Eina_Stringshare *
1013 show_file_entry_dialog(Browser_Window *window, const char *label_tag, const char *default_text)
1015 Evas_Object *file_popup = elm_popup_add(window->elm_window);
1016 evas_object_size_hint_weight_set(file_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1017 evas_object_show(file_popup);
1019 Evas_Object *vbox = elm_box_add(file_popup);
1020 evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1021 evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
1022 elm_object_content_set(file_popup, vbox);
1023 evas_object_show(vbox);
1025 Evas_Object *label = elm_label_add(window->elm_window);
1026 elm_object_text_set(label, label_tag);
1027 evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, 0.0);
1028 evas_object_size_hint_align_set(label, EVAS_HINT_FILL, 0.5);
1029 evas_object_color_set(label, 23, 45, 67, 142);
1030 elm_box_pack_end(vbox, label);
1031 evas_object_show(label);
1033 Evas_Object *fs_entry = elm_fileselector_entry_add(file_popup);
1034 elm_fileselector_entry_is_save_set(fs_entry, EINA_TRUE);
1035 evas_object_size_hint_align_set(fs_entry, EVAS_HINT_FILL, 0);
1036 elm_fileselector_entry_path_set(fs_entry, default_text);
1037 elm_object_text_set(fs_entry, "FileChooser");
1038 elm_box_pack_end(vbox, fs_entry);
1039 evas_object_show(fs_entry);
1041 Evas_Object *hbox = elm_box_add(file_popup);
1042 evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1043 elm_box_horizontal_set(hbox, EINA_TRUE);
1044 evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
1045 elm_box_pack_end(vbox, hbox);
1046 evas_object_show(hbox);
1048 Eina_Bool ok = EINA_FALSE;
1049 Evas_Object *ok_button = elm_button_add(file_popup);
1050 elm_object_text_set(ok_button, "OK");
1051 evas_object_smart_callback_add(ok_button, "clicked", on_ok_clicked, &ok);
1052 elm_box_pack_end(hbox, ok_button);
1053 evas_object_show(ok_button);
1055 Evas_Object *cancel_button = elm_button_add(file_popup);
1056 elm_object_text_set(cancel_button, "Cancel");
1057 evas_object_smart_callback_add(cancel_button, "clicked", quit_event_loop, NULL);
1058 elm_box_pack_end(hbox, cancel_button);
1059 evas_object_show(cancel_button);
1061 ecore_main_loop_begin();
1063 Eina_Stringshare *file_path = ok ? eina_stringshare_add(elm_fileselector_entry_path_get(fs_entry)) : NULL;
1064 evas_object_del(file_popup);
1069 on_javascript_alert(Ewk_View_Smart_Data *smartData, const char *message)
1071 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1073 Evas_Object *alert_popup = elm_popup_add(window->elm_window);
1074 evas_object_size_hint_weight_set(alert_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1075 elm_object_text_set(alert_popup, message);
1076 elm_object_part_text_set(alert_popup, "title,text", "Alert");
1079 Evas_Object *button = elm_button_add(alert_popup);
1080 elm_object_text_set(button, "OK");
1081 elm_object_part_content_set(alert_popup, "button1", button);
1082 evas_object_smart_callback_add(button, "clicked", quit_event_loop, NULL);
1083 elm_object_focus_set(button, EINA_TRUE);
1084 evas_object_show(alert_popup);
1087 ecore_main_loop_begin();
1089 evas_object_del(alert_popup);
1093 on_javascript_confirm(Ewk_View_Smart_Data *smartData, const char *message)
1095 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1097 Eina_Bool ok = EINA_FALSE;
1099 Evas_Object *confirm_popup = elm_popup_add(window->elm_window);
1100 evas_object_size_hint_weight_set(confirm_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1101 elm_object_text_set(confirm_popup, message);
1102 elm_object_part_text_set(confirm_popup, "title,text", "Confirmation");
1105 Evas_Object *cancel_button = elm_button_add(confirm_popup);
1106 elm_object_text_set(cancel_button, "Cancel");
1107 elm_object_part_content_set(confirm_popup, "button1", cancel_button);
1108 evas_object_smart_callback_add(cancel_button, "clicked", quit_event_loop, NULL);
1109 Evas_Object *ok_button = elm_button_add(confirm_popup);
1110 elm_object_text_set(ok_button, "OK");
1111 elm_object_part_content_set(confirm_popup, "button2", ok_button);
1112 evas_object_smart_callback_add(ok_button, "clicked", on_ok_clicked, &ok);
1113 elm_object_focus_set(ok_button, EINA_TRUE);
1114 evas_object_show(confirm_popup);
1117 ecore_main_loop_begin();
1119 evas_object_del(confirm_popup);
1125 on_javascript_prompt(Ewk_View_Smart_Data *smartData, const char *message, const char *default_value)
1127 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1129 Eina_Bool ok = EINA_FALSE;
1131 Evas_Object *prompt_popup = elm_popup_add(window->elm_window);
1132 evas_object_size_hint_weight_set(prompt_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1133 elm_object_part_text_set(prompt_popup, "title,text", "Prompt");
1136 Evas_Object *box = elm_box_add(window->elm_window);
1137 elm_box_padding_set(box, 0, 4);
1138 evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1139 evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
1140 evas_object_show(box);
1142 Evas_Object *prompt = elm_label_add(window->elm_window);
1143 elm_object_text_set(prompt, message);
1144 evas_object_size_hint_weight_set(prompt, EVAS_HINT_EXPAND, 0.0);
1145 evas_object_size_hint_align_set(prompt, EVAS_HINT_FILL, 0.5);
1146 elm_box_pack_end(box, prompt);
1147 evas_object_show(prompt);
1149 Evas_Object *entry = elm_entry_add(window->elm_window);
1150 elm_entry_scrollable_set(entry, EINA_TRUE);
1151 elm_entry_single_line_set(entry, EINA_TRUE);
1152 elm_entry_text_style_user_push(entry, "DEFAULT='font_size=18'");
1153 elm_entry_entry_set(entry, default_value ? default_value : "");
1154 elm_entry_select_all(entry);
1155 evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0);
1156 evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.5);
1157 elm_box_pack_end(box, entry);
1158 elm_object_focus_set(entry, EINA_TRUE);
1159 evas_object_show(entry);
1161 elm_object_content_set(prompt_popup, box);
1164 Evas_Object *cancel_button = elm_button_add(prompt_popup);
1165 elm_object_text_set(cancel_button, "Cancel");
1166 elm_object_part_content_set(prompt_popup, "button1", cancel_button);
1167 evas_object_smart_callback_add(cancel_button, "clicked", quit_event_loop, NULL);
1168 Evas_Object *ok_button = elm_button_add(prompt_popup);
1169 elm_object_text_set(ok_button, "OK");
1170 elm_object_part_content_set(prompt_popup, "button2", ok_button);
1171 evas_object_smart_callback_add(ok_button, "clicked", on_ok_clicked, &ok);
1172 evas_object_show(prompt_popup);
1175 ecore_main_loop_begin();
1177 /* The return string need to be stringshared */
1178 const char *prompt_text = ok ? eina_stringshare_add(elm_entry_entry_get(entry)) : NULL;
1179 evas_object_del(prompt_popup);
1185 on_popup_menu_discarded(void *user_data, Evas_Object *obj, void *event_info)
1187 // The user clicked outside the menu to discard it.
1188 info("Popup menu was discarded.");
1189 Browser_Window *window = (Browser_Window *)user_data;
1190 ewk_popup_menu_close(window->popup.ewk_menu);
1194 on_popup_menu_item_clicked(void *user_data, Evas_Object *obj, void *event_info)
1196 Browser_Window *window = (Browser_Window *)user_data;
1197 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
1199 info("Selected popup menu index: %u", elm_menu_item_index_get(item));
1200 ewk_popup_menu_selected_index_set(window->popup.ewk_menu, elm_menu_item_index_get(item));
1202 // Close popup menu.
1203 ewk_popup_menu_close(window->popup.ewk_menu);
1207 popup_menu_populate(Evas_Object *elm_menu, Ewk_Popup_Menu *ewk_menu, void *user_data)
1209 const Eina_List* ewk_items = ewk_popup_menu_items_get(ewk_menu);
1213 EINA_LIST_FOREACH(ewk_items, l, data) {
1214 Ewk_Popup_Menu_Item *ewk_item = (Ewk_Popup_Menu_Item *)data;
1215 switch (ewk_popup_menu_item_type_get(ewk_item)) {
1216 case EWK_POPUP_MENU_SEPARATOR:
1217 elm_menu_item_separator_add(elm_menu, NULL);
1219 case EWK_POPUP_MENU_ITEM:
1220 if (ewk_popup_menu_item_is_label_get(ewk_item)) {
1221 Elm_Object_Item *item = elm_menu_item_add(elm_menu, NULL, NULL, ewk_popup_menu_item_text_get(ewk_item), NULL, NULL);
1222 elm_object_item_disabled_set(item, EINA_TRUE);
1224 Elm_Object_Item *item = elm_menu_item_add(elm_menu, NULL, NULL, ewk_popup_menu_item_text_get(ewk_item), on_popup_menu_item_clicked, user_data);
1225 const char *tooltip_text = ewk_popup_menu_item_tooltip_get(ewk_item);
1226 if (tooltip_text && tooltip_text[0] != '\0')
1227 elm_object_item_tooltip_text_set(item, tooltip_text);
1228 elm_object_item_disabled_set(item, !ewk_popup_menu_item_enabled_get(ewk_item));
1229 elm_menu_item_selected_set(item, ewk_popup_menu_item_selected_get(ewk_item));
1233 info("Unrecognized popup menu item type!");
1240 on_popup_menu_show(Ewk_View_Smart_Data *smartData, Eina_Rectangle rect, Ewk_Text_Direction text_direction, double page_scale_factor, Ewk_Popup_Menu *ewk_menu)
1242 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1244 if (window->popup.elm_menu)
1245 evas_object_del(window->popup.elm_menu);
1247 window->popup.elm_menu = elm_menu_add(window->elm_window);
1248 window->popup.ewk_menu = ewk_menu;
1249 evas_object_smart_callback_add(window->popup.elm_menu, "clicked", on_popup_menu_discarded, window);
1251 popup_menu_populate(window->popup.elm_menu, ewk_menu, window);
1253 info("Showing popup menu at (%d, %d)", rect.x, rect.y);
1254 elm_menu_move(window->popup.elm_menu, rect.x, rect.y);
1255 evas_object_show(window->popup.elm_menu);
1261 on_popup_menu_hide(Ewk_View_Smart_Data *smartData)
1263 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1265 if (!window->popup.elm_menu)
1268 elm_menu_close(window->popup.elm_menu);
1273 static Eina_Bool on_window_geometry_get(Ewk_View_Smart_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *width, Evas_Coord *height)
1275 Browser_Window *window = window_find_with_ewk_view(sd->self);
1277 evas_object_geometry_get(window->elm_window, x, y, width, height);
1282 static Eina_Bool on_window_geometry_set(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height)
1284 Browser_Window *window = window_find_with_ewk_view(sd->self);
1286 evas_object_move(window->elm_window, x, y);
1287 evas_object_resize(window->elm_window, width, height);
1293 Evas_Object *ewk_view;
1294 Evas_Object *permission_popup;
1298 on_fullscreen_accept(void *user_data, Evas_Object *obj, void *event_info)
1300 PermissionData *permission_data = (PermissionData *)user_data;
1302 evas_object_del(permission_data->permission_popup);
1303 evas_object_focus_set(permission_data->ewk_view, EINA_TRUE);
1304 free(permission_data);
1308 on_fullscreen_deny(void *user_data, Evas_Object *obj, void *event_info)
1310 PermissionData *permission_data = (PermissionData *)user_data;
1312 ewk_view_fullscreen_exit(permission_data->ewk_view);
1313 evas_object_del(permission_data->permission_popup);
1314 evas_object_focus_set(permission_data->ewk_view, EINA_TRUE);
1315 free(permission_data);
1318 static Eina_Bool on_fullscreen_enter(Ewk_View_Smart_Data *sd, Ewk_Security_Origin *origin)
1320 Browser_Window *window = window_find_with_ewk_view(sd->self);
1323 elm_win_fullscreen_set(window->elm_window, EINA_TRUE);
1325 /* Show user popup */
1326 Evas_Object *permission_popup = elm_popup_add(window->elm_window);
1327 evas_object_size_hint_weight_set(permission_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1329 Eina_Strbuf *message = eina_strbuf_new();
1330 eina_strbuf_append_printf(message, "%s is now fullscreen.<br>Press ESC at any time to exit fullscreen.<br>Allow fullscreen?", ewk_security_origin_host_get(origin));
1331 elm_object_text_set(permission_popup, eina_strbuf_string_get(message));
1332 eina_strbuf_free(message);
1333 elm_object_part_text_set(permission_popup, "title,text", "Fullscreen Permission");
1336 PermissionData *permission_data = (PermissionData *)malloc(sizeof(PermissionData));
1337 permission_data->ewk_view = window->ewk_view;
1338 permission_data->permission_popup = permission_popup;
1339 Evas_Object *accept_button = elm_button_add(permission_popup);
1340 elm_object_text_set(accept_button, "Accept");
1341 elm_object_part_content_set(permission_popup, "button1", accept_button);
1342 evas_object_smart_callback_add(accept_button, "clicked", on_fullscreen_accept, permission_data);
1344 Evas_Object *deny_button = elm_button_add(permission_popup);
1345 elm_object_text_set(deny_button, "Deny");
1346 elm_object_part_content_set(permission_popup, "button2", deny_button);
1347 evas_object_smart_callback_add(deny_button, "clicked", on_fullscreen_deny, permission_data);
1349 evas_object_show(permission_popup);
1354 static Eina_Bool on_fullscreen_exit(Ewk_View_Smart_Data *sd)
1356 Browser_Window *window = window_find_with_ewk_view(sd->self);
1358 elm_win_fullscreen_set(window->elm_window, EINA_FALSE);
1363 static Evas_Object *
1364 on_window_create(Ewk_View_Smart_Data *smartData, const Ewk_Window_Features *window_features)
1371 ewk_window_features_geometry_get(window_features, &x, &y, &width, &height);
1374 width = window_width;
1377 height = window_height;
1379 Browser_Window *window = window_create(smartData->self, width, height);
1380 Evas_Object *new_view = window->ewk_view;
1382 windows = eina_list_append(windows, window);
1384 info("minibrowser: location(%d,%d) size=(%d,%d)", x, y, width, height);
1390 on_window_close(Ewk_View_Smart_Data *smartData)
1392 Browser_Window *window = window_find_with_ewk_view(smartData->self);
1393 window_close(window);
1397 context_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
1400 info("ERROR: context menu callback data is NULL.");
1404 Ewk_Context_Menu_Item *ewk_item = (Ewk_Context_Menu_Item *)data;
1405 info("Selected context menu item: %s.", ewk_context_menu_item_title_get(ewk_item));
1406 ewk_context_menu_item_select(ewk_context_menu_item_parent_menu_get(ewk_item), ewk_item);
1407 ewk_context_menu_hide(ewk_context_menu_item_parent_menu_get(ewk_item));
1411 context_menu_populate(Evas_Object* context_menu, Ewk_Context_Menu *ewk_menu, Elm_Object_Item *parent_item)
1413 if (!context_menu || !ewk_menu) {
1414 info("ERROR: necessary objects are NULL.");
1418 const Eina_List *list = ewk_context_menu_items_get(ewk_menu);
1422 Ewk_Context_Menu_Item *ewk_item;
1423 Elm_Object_Item *elm_menu_item;
1424 Evas_Object *elm_check_item;
1426 EINA_LIST_FOREACH(list, l, data) {
1427 ewk_item = (Ewk_Context_Menu_Item *)data;
1428 switch (ewk_context_menu_item_type_get(ewk_item)) {
1429 case EWK_ACTION_TYPE:
1430 elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), context_menu_item_selected_cb, ewk_item);
1432 case EWK_CHECKABLE_ACTION_TYPE:
1433 elm_check_item = elm_check_add(context_menu);
1434 elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), context_menu_item_selected_cb, ewk_item);
1435 elm_object_item_content_set(elm_menu_item, elm_check_item);
1436 elm_check_state_set(elm_check_item, ewk_context_menu_item_checked_get(ewk_item));
1438 case EWK_SUBMENU_TYPE:
1439 elm_menu_item = elm_menu_item_add(context_menu, parent_item, NULL, ewk_context_menu_item_title_get(ewk_item), NULL, ewk_item);
1441 context_menu_populate(context_menu, ewk_context_menu_item_submenu_get(ewk_item), elm_menu_item);
1446 elm_object_item_disabled_set(elm_menu_item, !ewk_context_menu_item_enabled_get(ewk_item));
1451 on_context_menu_show(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Ewk_Context_Menu *menu)
1453 Browser_Window *window = window_find_with_ewk_view(sd->self);
1455 if (!window || !menu) {
1456 info("ERROR: necessary objects are NULL.");
1460 window->context_menu.elm_menu = elm_menu_add(window->elm_window);
1462 if (!window->context_menu.elm_menu) {
1463 info("ERROR: could not create menu widget.");
1467 window->context_menu.ewk_menu = menu;
1469 context_menu_populate(window->context_menu.elm_menu, menu, NULL);
1471 info("Showing context menu at (%d, %d).", x, y);
1472 elm_menu_move(window->context_menu.elm_menu, x, y);
1473 evas_object_show(window->context_menu.elm_menu);
1479 on_context_menu_hide(Ewk_View_Smart_Data *sd)
1481 Browser_Window *window = window_find_with_ewk_view(sd->self);
1483 if (!window || !window->context_menu.elm_menu) {
1484 info("ERROR: necessary objects are NULL.");
1488 elm_menu_close(window->context_menu.elm_menu);
1489 evas_object_del(window->context_menu.elm_menu);
1490 window->context_menu.elm_menu = NULL;
1491 window->context_menu.ewk_menu = NULL;
1497 auth_popup_close(Auth_Data *auth_data)
1499 ewk_object_unref(auth_data->request);
1500 evas_object_del(auth_data->popup);
1505 on_auth_cancel(void *user_data, Evas_Object *obj, void *event_info)
1507 Auth_Data *auth_data = (Auth_Data *)user_data;
1509 ewk_auth_request_cancel(auth_data->request);
1511 auth_popup_close(auth_data);
1515 on_auth_ok(void *user_data, Evas_Object *obj, void *event_info)
1517 Auth_Data *auth_data = (Auth_Data *)user_data;
1519 const char *username = elm_entry_entry_get(auth_data->username_entry);
1520 const char *password = elm_entry_entry_get(auth_data->password_entry);
1521 ewk_auth_request_authenticate(auth_data->request, username, password);
1523 auth_popup_close(auth_data);
1527 on_authentication_request(void *user_data, Evas_Object *obj, void *event_info)
1529 Browser_Window *window = (Browser_Window *)user_data;
1530 Ewk_Auth_Request *request = ewk_object_ref((Ewk_Auth_Request *)event_info);
1532 Auth_Data *auth_data = (Auth_Data *)malloc(sizeof(Auth_Data));
1533 auth_data->request = request;
1535 Evas_Object *auth_popup = elm_popup_add(window->elm_window);
1536 auth_data->popup = auth_popup;
1537 evas_object_size_hint_weight_set(auth_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1538 elm_object_part_text_set(auth_popup, "title,text", "Authentication Required");
1541 Evas_Object *vbox = elm_box_add(auth_popup);
1542 elm_box_padding_set(vbox, 0, 4);
1543 evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1544 evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
1545 elm_object_content_set(auth_popup, vbox);
1546 evas_object_show(vbox);
1548 /* Authentication message */
1549 Evas_Object *label = elm_label_add(auth_popup);
1550 elm_label_line_wrap_set(label, ELM_WRAP_WORD);
1551 Eina_Strbuf *auth_text = eina_strbuf_new();
1552 const char *host = ewk_auth_request_host_get(request);
1553 const char *realm = ewk_auth_request_realm_get(request);
1554 eina_strbuf_append_printf(auth_text, "A username and password are being requested by %s. The site says: \"%s\"", host, realm ? realm : "");
1555 elm_object_text_set(label, eina_strbuf_string_get(auth_text));
1556 eina_strbuf_free(auth_text);
1557 evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1558 evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
1559 elm_box_pack_end(vbox, label);
1560 evas_object_show(label);
1562 /* Credential table */
1563 Evas_Object *table = elm_table_add(auth_popup);
1564 elm_table_padding_set(table, 2, 2);
1565 elm_table_homogeneous_set(table, EINA_TRUE);
1566 evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1567 evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
1568 elm_box_pack_end(vbox, table);
1569 evas_object_show(table);
1572 Evas_Object *username_label = elm_label_add(auth_popup);
1573 elm_object_text_set(username_label, "Username:");
1574 evas_object_size_hint_weight_set(username_label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1575 evas_object_size_hint_align_set(username_label, 1, EVAS_HINT_FILL);
1576 elm_table_pack(table, username_label, 0, 0, 1, 1);
1577 evas_object_show(username_label);
1579 Evas_Object *username_entry = elm_entry_add(auth_popup);
1580 auth_data->username_entry = username_entry;
1581 elm_entry_scrollable_set(username_entry, EINA_TRUE);
1582 elm_entry_single_line_set(username_entry, EINA_TRUE);
1583 elm_entry_text_style_user_push(username_entry, "DEFAULT='font_size=18'");
1584 const char *suggested_username = ewk_auth_request_suggested_username_get(request);
1585 elm_entry_entry_set(username_entry, suggested_username ? suggested_username : "");
1586 evas_object_size_hint_weight_set(username_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1587 evas_object_size_hint_align_set(username_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
1588 elm_table_pack(table, username_entry, 1, 0, 2, 1);
1589 elm_object_focus_set(username_entry, EINA_TRUE);
1590 evas_object_show(username_entry);
1593 Evas_Object *password_label = elm_label_add(auth_popup);
1594 elm_object_text_set(password_label, "Password:");
1595 evas_object_size_hint_weight_set(password_label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1596 evas_object_size_hint_align_set(password_label, 1, EVAS_HINT_FILL);
1597 elm_table_pack(table, password_label, 0, 1, 1, 1);
1598 evas_object_show(password_label);
1600 Evas_Object *password_entry = elm_entry_add(auth_popup);
1601 auth_data->password_entry = password_entry;
1602 elm_entry_scrollable_set(password_entry, EINA_TRUE);
1603 elm_entry_single_line_set(password_entry, EINA_TRUE);
1604 elm_entry_password_set(password_entry, EINA_TRUE);
1605 elm_entry_text_style_user_push(password_entry, "DEFAULT='font_size=18'");
1606 evas_object_size_hint_weight_set(password_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1607 evas_object_size_hint_align_set(password_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
1608 elm_table_pack(table, password_entry, 1, 1, 2, 1);
1609 evas_object_show(password_entry);
1612 Evas_Object *cancel_button = elm_button_add(auth_popup);
1613 elm_object_text_set(cancel_button, "Cancel");
1614 elm_object_part_content_set(auth_popup, "button1", cancel_button);
1615 evas_object_smart_callback_add(cancel_button, "clicked", on_auth_cancel, auth_data);
1616 Evas_Object *ok_button = elm_button_add(auth_popup);
1617 elm_object_text_set(ok_button, "OK");
1618 elm_object_part_content_set(auth_popup, "button2", ok_button);
1619 evas_object_smart_callback_add(ok_button, "clicked", on_auth_ok, auth_data);
1620 evas_object_show(auth_popup);
1624 on_tooltip_text_set(void *user_data, Evas_Object *obj, void *event_info)
1626 Browser_Window *window = (Browser_Window *)user_data;
1627 const char *message = (const char*)event_info;
1629 elm_object_tooltip_text_set(window->elm_window, message);
1630 window->tooltip.text_set = EINA_TRUE;
1631 window_tooltip_update(window);
1635 on_tooltip_text_unset(void *user_data, Evas_Object *obj, void *event_info)
1637 Browser_Window *window = (Browser_Window *)user_data;
1639 window_tooltip_hide(window);
1640 elm_object_tooltip_unset(window->elm_window);
1641 window->tooltip.text_set = EINA_FALSE;
1645 on_home_button_clicked(void *user_data, Evas_Object *home_button, void *event_info)
1647 Browser_Window *window = (Browser_Window *)user_data;
1649 ewk_view_url_set(window->ewk_view, DEFAULT_URL);
1653 on_window_deletion(void *user_data, Evas_Object *elm_window, void *event_info)
1655 window_close(window_find_with_elm_window(elm_window));
1658 static Evas_Object *
1659 create_toolbar_button(Evas_Object *elm_window, const char *icon_name)
1661 Evas_Object *button = elm_button_add(elm_window);
1663 Evas_Object *icon = elm_icon_add(elm_window);
1664 elm_icon_standard_set(icon, icon_name);
1665 evas_object_size_hint_max_set(icon, TOOL_BAR_ICON_SIZE, TOOL_BAR_ICON_SIZE);
1666 evas_object_color_set(icon, 44, 44, 102, 128);
1667 evas_object_show(icon);
1668 elm_object_part_content_set(button, "icon", icon);
1669 evas_object_size_hint_min_set(button, TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
1674 static Browser_Window *window_create(Evas_Object *opener, int width, int height)
1676 Browser_Window *window = calloc(1, sizeof(Browser_Window));
1678 info("ERROR: could not create browser window.");
1682 /* Initialize tooltip information */
1683 window->tooltip.show_timer = NULL;
1684 window->tooltip.activated = EINA_FALSE;
1685 window->tooltip.text_set = EINA_FALSE;
1686 window->tooltip.shown = EINA_FALSE;
1689 window->elm_window = elm_win_add(NULL, "minibrowser-window", ELM_WIN_BASIC);
1690 elm_win_title_set(window->elm_window, APP_NAME);
1691 evas_object_smart_callback_add(window->elm_window, "delete,request", on_window_deletion, &window);
1693 /* Create window background */
1694 Evas_Object *bg = elm_bg_add(window->elm_window);
1695 elm_bg_color_set(bg, 193, 192, 191);
1696 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1697 elm_win_resize_object_add(window->elm_window, bg);
1698 evas_object_show(bg);
1700 /* Create vertical layout */
1701 Evas_Object *vertical_layout = elm_box_add(window->elm_window);
1702 elm_box_padding_set(vertical_layout, 0, 2);
1703 evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1704 elm_win_resize_object_add(window->elm_window, vertical_layout);
1705 evas_object_show(vertical_layout);
1707 /* Create horizontal layout for top bar */
1708 Evas_Object *horizontal_layout = elm_box_add(window->elm_window);
1709 elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
1710 evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
1711 evas_object_size_hint_align_set(horizontal_layout, EVAS_HINT_FILL, 0.0);
1712 elm_box_pack_end(vertical_layout, horizontal_layout);
1713 evas_object_show(horizontal_layout);
1715 /* Create Back button */
1716 window->back_button = create_toolbar_button(window->elm_window, "arrow_left");
1717 evas_object_smart_callback_add(window->back_button, "clicked", on_back_button_clicked, window);
1718 elm_object_disabled_set(window->back_button, EINA_TRUE);
1719 evas_object_size_hint_weight_set(window->back_button, 0.0, EVAS_HINT_EXPAND);
1720 evas_object_size_hint_align_set(window->back_button, 0.0, 0.5);
1721 elm_box_pack_end(horizontal_layout, window->back_button);
1722 evas_object_show(window->back_button);
1724 /* Create Forward button */
1725 window->forward_button = create_toolbar_button(window->elm_window, "arrow_right");
1726 evas_object_smart_callback_add(window->forward_button, "clicked", on_forward_button_clicked, window);
1727 elm_object_disabled_set(window->forward_button, EINA_TRUE);
1728 evas_object_size_hint_weight_set(window->forward_button, 0.0, EVAS_HINT_EXPAND);
1729 evas_object_size_hint_align_set(window->forward_button, 0.0, 0.5);
1730 elm_box_pack_end(horizontal_layout, window->forward_button);
1731 evas_object_show(window->forward_button);
1733 /* Create URL bar */
1734 window->url_bar = elm_entry_add(window->elm_window);
1735 elm_entry_scrollable_set(window->url_bar, EINA_TRUE);
1736 elm_entry_scrollbar_policy_set(window->url_bar, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
1737 elm_entry_single_line_set(window->url_bar, EINA_TRUE);
1738 elm_entry_cnp_mode_set(window->url_bar, ELM_CNP_MODE_PLAINTEXT);
1739 elm_entry_text_style_user_push(window->url_bar, "DEFAULT='font_size=18'");
1740 evas_object_smart_callback_add(window->url_bar, "activated", on_url_bar_activated, window);
1741 evas_object_smart_callback_add(window->url_bar, "clicked", on_url_bar_clicked, window);
1742 evas_object_size_hint_weight_set(window->url_bar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1743 evas_object_size_hint_align_set(window->url_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
1744 elm_box_pack_end(horizontal_layout, window->url_bar);
1745 evas_object_show(window->url_bar);
1747 /* Create Refresh button */
1748 Evas_Object *refresh_button = create_toolbar_button(window->elm_window, "refresh");
1749 evas_object_smart_callback_add(refresh_button, "clicked", on_refresh_button_clicked, window);
1750 evas_object_size_hint_weight_set(refresh_button, 0.0, EVAS_HINT_EXPAND);
1751 evas_object_size_hint_align_set(refresh_button, 1.0, 0.5);
1752 elm_box_pack_end(horizontal_layout, refresh_button);
1753 evas_object_show(refresh_button);
1755 /* Create Home button */
1756 Evas_Object *home_button = create_toolbar_button(window->elm_window, "home");
1757 evas_object_smart_callback_add(home_button, "clicked", on_home_button_clicked, window);
1758 evas_object_size_hint_weight_set(home_button, 0.0, EVAS_HINT_EXPAND);
1759 evas_object_size_hint_align_set(home_button, 1.0, 0.5);
1760 elm_box_pack_end(horizontal_layout, home_button);
1761 evas_object_show(home_button);
1763 /* Create Search bar */
1764 window->search.search_bar = elm_box_add(window->elm_window);
1765 elm_box_horizontal_set(window->search.search_bar, EINA_TRUE);
1766 evas_object_size_hint_min_set(window->search.search_bar, SEARCH_FIELD_SIZE + 2 * SEARCH_BUTTON_SIZE, 0);
1767 evas_object_size_hint_align_set(window->search.search_bar, 0.0, EVAS_HINT_FILL);
1768 elm_box_pack_end(vertical_layout, window->search.search_bar);
1770 /* Create Search field */
1771 window->search.search_field = elm_entry_add(window->elm_window);
1772 elm_entry_scrollable_set(window->search.search_field, EINA_TRUE);
1773 elm_entry_scrollbar_policy_set(window->search.search_field, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
1774 elm_entry_single_line_set(window->search.search_field, EINA_TRUE);
1775 elm_entry_cnp_mode_set(window->search.search_field, ELM_CNP_MODE_PLAINTEXT);
1776 elm_entry_text_style_user_push(window->search.search_field, "DEFAULT='font_size=14'");
1777 evas_object_smart_callback_add(window->search.search_field, "activated", on_search_field_activated, window);
1778 evas_object_smart_callback_add(window->search.search_field, "changed", on_search_field_activated, window);
1779 evas_object_smart_callback_add(window->search.search_field, "aborted", on_search_field_aborted, window);
1780 evas_object_smart_callback_add(window->search.search_field, "clicked", on_search_field_clicked, window);
1781 evas_object_size_hint_weight_set(window->search.search_field, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1782 evas_object_size_hint_align_set(window->search.search_field, EVAS_HINT_FILL, EVAS_HINT_FILL);
1783 elm_box_pack_end(window->search.search_bar, window->search.search_field);
1785 /* Create Search backward button */
1786 window->search.backward_button = create_toolbar_button(window->elm_window, "arrow_up");
1787 evas_object_smart_callback_add(window->search.backward_button, "clicked", on_search_backward_button_clicked, window);
1788 elm_object_disabled_set(window->search.backward_button, EINA_FALSE);
1789 evas_object_size_hint_weight_set(window->search.backward_button, 0.0, EVAS_HINT_EXPAND);
1790 evas_object_size_hint_align_set(window->search.backward_button, 1.0, 0.5);
1791 evas_object_size_hint_min_set(window->search.backward_button, SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
1792 elm_box_pack_end(window->search.search_bar, window->search.backward_button);
1794 /* Create Search forwardward button */
1795 window->search.forward_button = create_toolbar_button(window->elm_window, "arrow_down");
1796 evas_object_smart_callback_add(window->search.forward_button, "clicked", on_search_forward_button_clicked, window);
1797 elm_object_disabled_set(window->search.forward_button, EINA_FALSE);
1798 evas_object_size_hint_weight_set(window->search.forward_button, 0.0, EVAS_HINT_EXPAND);
1799 evas_object_size_hint_align_set(window->search.forward_button, 1.0, 0.5);
1800 evas_object_size_hint_min_set(window->search.forward_button, SEARCH_BUTTON_SIZE, SEARCH_BUTTON_SIZE);
1801 elm_box_pack_end(window->search.search_bar, window->search.forward_button);
1803 /* Create ewk_view */
1804 Ewk_View_Smart_Class *ewkViewClass = miniBrowserViewSmartClass();
1805 ewkViewClass->run_javascript_alert = on_javascript_alert;
1806 ewkViewClass->run_javascript_confirm = on_javascript_confirm;
1807 ewkViewClass->run_javascript_prompt = on_javascript_prompt;
1808 ewkViewClass->window_geometry_get = on_window_geometry_get;
1809 ewkViewClass->window_geometry_set = on_window_geometry_set;
1810 ewkViewClass->fullscreen_enter = on_fullscreen_enter;
1811 ewkViewClass->fullscreen_exit = on_fullscreen_exit;
1812 ewkViewClass->window_create = on_window_create;
1813 ewkViewClass->window_close = on_window_close;
1814 ewkViewClass->popup_menu_show = on_popup_menu_show;
1815 ewkViewClass->popup_menu_hide = on_popup_menu_hide;
1816 ewkViewClass->context_menu_show = on_context_menu_show;
1817 ewkViewClass->context_menu_hide = on_context_menu_hide;
1818 ewkViewClass->input_picker_color_request = on_color_picker_request;
1819 ewkViewClass->input_picker_color_dismiss = on_color_picker_dismiss;
1821 Evas *evas = evas_object_evas_get(window->elm_window);
1822 Evas_Smart *smart = evas_smart_class_new(&ewkViewClass->sc);
1823 Ewk_Context *context = opener ? ewk_view_context_get(opener) : ewk_context_default_get();
1824 Ewk_Page_Group *pageGroup = opener ? ewk_view_page_group_get(opener) : ewk_page_group_create("");
1825 window->ewk_view = ewk_view_smart_add(evas, smart, context, pageGroup);
1827 ewk_view_theme_set(window->ewk_view, TEST_THEME_DIR "/default.edj");
1828 if (device_pixel_ratio)
1829 ewk_view_device_pixel_ratio_set(window->ewk_view, (float)device_pixel_ratio);
1830 ewk_view_user_agent_set(window->ewk_view, user_agent_string);
1831 ewk_view_layout_fixed_set(window->ewk_view, fixed_layout_enabled);
1833 if (touch_events_enabled) {
1834 ewk_view_touch_events_enabled_set(window->ewk_view, EINA_TRUE);
1835 ewk_view_mouse_events_enabled_set(window->ewk_view, EINA_FALSE);
1838 /* Set the zoom level to default */
1839 window->current_zoom_level = DEFAULT_ZOOM_LEVEL;
1841 Ewk_Settings *settings = ewk_view_settings_get(window->ewk_view);
1842 ewk_settings_file_access_from_file_urls_allowed_set(settings, EINA_TRUE);
1843 ewk_settings_encoding_detector_enabled_set(settings, encoding_detector_enabled);
1844 ewk_settings_frame_flattening_enabled_set(settings, frame_flattening_enabled);
1845 ewk_settings_local_storage_enabled_set(settings, local_storage_enabled);
1846 info("HTML5 local storage is %s for this view.", local_storage_enabled ? "enabled" : "disabled");
1847 elm_win_fullscreen_set(window->elm_window, fullscreen_enabled);
1848 ewk_settings_developer_extras_enabled_set(settings, EINA_TRUE);
1849 ewk_settings_preferred_minimum_contents_width_set(settings, 0);
1850 ewk_text_checker_continuous_spell_checking_enabled_set(spell_checking_enabled);
1852 evas_object_smart_callback_add(window->ewk_view, "authentication,request", on_authentication_request, window);
1853 evas_object_smart_callback_add(window->ewk_view, "download,failed", on_download_failed, window);
1854 evas_object_smart_callback_add(window->ewk_view, "download,finished", on_download_finished, window);
1855 evas_object_smart_callback_add(window->ewk_view, "download,request", on_download_request, window);
1856 evas_object_smart_callback_add(window->ewk_view, "file,chooser,request", on_file_chooser_request, window);
1857 evas_object_smart_callback_add(window->ewk_view, "favicon,changed", on_view_favicon_changed, window);
1858 evas_object_smart_callback_add(window->ewk_view, "load,error", on_error, window);
1859 evas_object_smart_callback_add(window->ewk_view, "load,provisional,failed", on_error, window);
1860 evas_object_smart_callback_add(window->ewk_view, "load,progress", on_progress, window);
1861 evas_object_smart_callback_add(window->ewk_view, "title,changed", on_title_changed, window);
1862 evas_object_smart_callback_add(window->ewk_view, "url,changed", on_url_changed, window);
1863 evas_object_smart_callback_add(window->ewk_view, "back,forward,list,changed", on_back_forward_list_changed, window);
1864 evas_object_smart_callback_add(window->ewk_view, "tooltip,text,set", on_tooltip_text_set, window);
1865 evas_object_smart_callback_add(window->ewk_view, "tooltip,text,unset", on_tooltip_text_unset, window);
1867 evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_KEY_DOWN, on_key_down, window);
1868 evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down, window);
1870 evas_object_size_hint_weight_set(window->ewk_view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1871 evas_object_size_hint_align_set(window->ewk_view, EVAS_HINT_FILL, EVAS_HINT_FILL);
1872 elm_box_pack_before(vertical_layout, window->ewk_view, window->search.search_bar);
1873 evas_object_show(window->ewk_view);
1875 evas_object_resize(window->elm_window, width ? width : window_width, height ? height : window_height);
1876 evas_object_show(window->elm_window);
1877 search_box_hide(window);
1879 view_focus_set(window, EINA_TRUE);
1881 evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_MOUSE_IN, on_mouse_in, window);
1882 evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_MOUSE_OUT, on_mouse_out, window);
1883 evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_MOUSE_MOVE, on_mouse_move, window);
1884 evas_object_event_callback_add(window->elm_window, EVAS_CALLBACK_RESIZE, on_window_resize, window);
1889 static Ewk_Cookie_Accept_Policy
1890 parse_cookies_policy(const char *input_string)
1892 if (!strcmp(input_string, "always"))
1893 return EWK_COOKIE_ACCEPT_POLICY_ALWAYS;
1894 if (!strcmp(input_string, "never"))
1895 return EWK_COOKIE_ACCEPT_POLICY_NEVER;
1896 if (strcmp(input_string, "no-third-party"))
1897 info("Unrecognized type for cookies policy: %s.", input_string);
1898 return EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY;
1902 parse_window_size(const char *input_string, int *width, int *height)
1904 static const unsigned max_length = 4;
1910 arr = eina_str_split_full(input_string, "x", 0, &elements);
1912 if (elements == 2 && (strlen(arr[0]) <= max_length) && (strlen(arr[1]) <= max_length)) {
1913 parsed_width = atoi(arr[0]);
1914 if (width && parsed_width)
1915 *width = parsed_width;
1917 parsed_height = atoi(arr[1]);
1918 if (height && parsed_height)
1919 *height = parsed_height;
1927 elm_main(int argc, char *argv[])
1930 unsigned char quitOption = 0;
1931 Browser_Window *window;
1932 char *window_size_string = NULL;
1933 char *cookies_policy_string = NULL;
1935 Ecore_Getopt_Value values[] = {
1936 ECORE_GETOPT_VALUE_STR(evas_engine_name),
1937 ECORE_GETOPT_VALUE_STR(window_size_string),
1938 ECORE_GETOPT_VALUE_STR(user_agent_string),
1939 ECORE_GETOPT_VALUE_DOUBLE(device_pixel_ratio),
1940 ECORE_GETOPT_VALUE_BOOL(quitOption),
1941 ECORE_GETOPT_VALUE_BOOL(encoding_detector_enabled),
1942 ECORE_GETOPT_VALUE_BOOL(frame_flattening_enabled),
1943 ECORE_GETOPT_VALUE_BOOL(local_storage_enabled),
1944 ECORE_GETOPT_VALUE_BOOL(fullscreen_enabled),
1945 ECORE_GETOPT_VALUE_BOOL(spell_checking_enabled),
1946 ECORE_GETOPT_VALUE_BOOL(touch_events_enabled),
1947 ECORE_GETOPT_VALUE_BOOL(fixed_layout_enabled),
1948 ECORE_GETOPT_VALUE_STR(cookies_policy_string),
1949 ECORE_GETOPT_VALUE_BOOL(quitOption),
1950 ECORE_GETOPT_VALUE_BOOL(quitOption),
1951 ECORE_GETOPT_VALUE_BOOL(quitOption),
1952 ECORE_GETOPT_VALUE_NONE
1956 return EXIT_FAILURE;
1958 ewk_view_smart_class_set(miniBrowserViewSmartClass());
1960 ecore_app_args_set(argc, (const char **) argv);
1961 args = ecore_getopt_parse(&options, values, argc, argv);
1964 return quit(EINA_FALSE, "ERROR: could not parse options.\n");
1967 return quit(EINA_TRUE, NULL);
1969 if (evas_engine_name)
1970 elm_config_preferred_engine_set(evas_engine_name);
1971 #if defined(HAVE_ECORE_X)
1973 evas_engine_name = "opengl_x11";
1974 elm_config_preferred_engine_set(evas_engine_name);
1978 // Enable favicon database.
1979 Ewk_Context *context = ewk_context_default_get();
1980 ewk_context_favicon_database_directory_set(context, NULL);
1982 if (cookies_policy_string)
1983 ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(context), parse_cookies_policy(cookies_policy_string));
1985 if (window_size_string)
1986 parse_window_size(window_size_string, &window_width, &window_height);
1989 char *url = url_from_user_input(argv[args]);
1990 window = window_create(NULL, 0, 0);
1991 ewk_view_url_set(window->ewk_view, url);
1994 window = window_create(NULL, 0, 0);
1995 ewk_view_url_set(window->ewk_view, DEFAULT_URL);
1999 return quit(EINA_FALSE, "ERROR: could not create browser window.\n");
2001 windows = eina_list_append(windows, window);
2005 return quit(EINA_TRUE, NULL);