buffer.c (14254B)
1 2 #include <Elementary.h> 3 #include <EWebKit2.h> 4 5 #include "viking_state.h" 6 #include "viking.h" 7 #include "javascript.h" 8 #include "utilities.h" 9 #include "commands.h" 10 #include "window.h" 11 #include "buffer.h" 12 #include "buffer_callback.h" 13 #include "download.h" 14 15 16 Ewk_View_Smart_Class* miniBrowserViewSmartClass(void) 17 { 18 static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("MiniBrowser_View"); 19 return &ewkViewClass; 20 } 21 22 /* 23 static Browser_Window *browser_view_find(Evas_Object *view) 24 { 25 Eina_List *l; 26 void *data; 27 28 if (!view) 29 return NULL; 30 31 EINA_LIST_FOREACH(windows, l, data) { 32 Browser_Window *browser_window = (Browser_Window *)data; 33 if (browser_window->webview == view) 34 return browser_window; 35 } 36 return NULL; 37 } 38 */ 39 40 41 /* 42 static void 43 webview_create_window_cb(void *data, Evas_Object *obj, Eina_Bool js, const Elm_Web_Window_Features *wf) 44 { 45 Arg a; 46 Window_Data *wd = data; 47 48 buffer_add(&a, wd); 49 } 50 */ 51 52 static void 53 title_changed_cb(void *data, Evas_Object *obj, void *event_info) 54 { 55 Buffer_Data *bd = data; 56 Window_Data *wd = bd->window; 57 const char *title = event_info; 58 char buf[128] = ""; 59 60 if (title) 61 strncpy(buf, title, sizeof(buf) - 1); 62 63 elm_win_title_set(wd->win, buf); 64 } 65 66 static void 67 load_progress_cb(void *data, Evas_Object *obj, void *event_info) 68 { 69 Buffer_Data *bd = data; 70 Window_Data *wd = bd->window; 71 double *val = event_info; 72 73 if (bd != bd->window->cur_buf) 74 return; 75 76 elm_progressbar_value_set(wd->progress_bar, *val); 77 78 /* 79 if (*val == 1.0) 80 evas_object_hide(wd->progress_bar); 81 else 82 evas_object_show(wd->progress_bar); 83 */ 84 } 85 86 static void 87 storage_origins_cb(Eina_List *origins, Ewk_Error *error, void *user_data) 88 { 89 /* 90 Eina_List *l; 91 Ewk_Security_Origin *sec; 92 93 printf("storage_origins_cb() has %i origins\n", eina_list_count(origins)); 94 95 EINA_LIST_FOREACH(origins, l, sec) { 96 printf(" -> %s://%s port %i\n", 97 ewk_security_origin_protocol_get(sec), 98 ewk_security_origin_host_get(sec), 99 ewk_security_origin_port_get(sec)); 100 } 101 */ 102 } 103 104 static void 105 url_changed_cb(void *data, Evas_Object *obj, void *event_info) 106 { 107 Buffer_Data *bd = data; 108 Window_Data *wd = bd->window; 109 const char *url = event_info; 110 // Arg a = { .i = Silent, .s = strdup(JS_SETUP_HINTS) }; 111 112 if (bd != wd->cur_buf) 113 return; 114 115 // userscript_hooks_start(elm_web_uri_get(td->web)); 116 // script(&a, bd->window); 117 // free(a.s); 118 119 if (bd->window->mode == ModeInsert || bd->window->mode == ModeHints) { 120 Arg a = { .i = ModeNormal }; 121 set(&a, bd->window); 122 } 123 124 bd->window->manual_focus = EINA_FALSE; 125 126 if (strncmp(url, "http://", 7) == 0) 127 url += 7; 128 else if (strncmp(url, "https://", 8) == 0) 129 url += 8; 130 elm_object_text_set(wd->status_url, url); 131 evas_object_show(wd->status_url); 132 133 // ewk_storage_manager_origins_get(ewk_context_storage_manager_get(ewk_context_default_get()), storage_origins_cb, bd); 134 } 135 136 static void 137 load_finished_cb(void *data, Evas_Object *obj, void *event_info) 138 { 139 Buffer_Data *bd = data; 140 Window_Data *wd = bd->window; 141 Eina_Bool scripts = 1; 142 143 /* g_object_get(settings, "enable-scripts", &scripts, NULL); */ 144 /* TRUE will disable automatic focusing of input fields via Javascript*/ 145 static Eina_Bool escape_input_on_load = EINA_TRUE; 146 if (escape_input_on_load && scripts && !wd->manual_focus && !elm_object_focus_get(wd->url)) { 147 Arg a = { .i = Silent, .s = strdup("hints.clearFocus();") }; 148 script(&a, wd); 149 free(a.s); 150 a.i = ModeNormal; 151 a.s = NULL; 152 set(&a, wd); 153 } 154 155 // userscript_hooks_end(elm_web_uri_get(td->web)); 156 } 157 158 static void 159 load_error_cb(void *data, Evas_Object *webview, void *event_info) 160 { 161 Eina_Strbuf* buffer; 162 const Ewk_Error *error = event_info; 163 unsigned int error_code = ewk_error_code_get(error); 164 165 /* This is a cancellation, do not display the error page */ 166 if (ewk_error_cancellation_get(error)) 167 return; 168 169 if (error_code == 204) 170 /* plugin will handle load, no need to report error */ 171 return; 172 173 buffer = eina_strbuf_new(); 174 eina_strbuf_append_printf(buffer, "<html><body><div style=\"background-color:rgba(0, 0, 200, 0.5);\">ERROR!</div><br><div>Code: %d<br>Description: %s<br>URL: %s</div></body</html>", 175 error_code, ewk_error_description_get(error), ewk_error_url_get(error)); 176 177 ewk_view_html_string_load(webview, eina_strbuf_string_get(buffer), 0, ewk_error_url_get(error)); 178 eina_strbuf_free(buffer); 179 } 180 181 static Eina_Bool 182 process_keypress(void *event_info, Window_Data *wd) 183 { 184 Key key, *inc_key; 185 App_Data *ad = wd->app; 186 Evas_Event_Key_Down *ev = event_info; 187 Eina_List *l; 188 189 EINA_LIST_FOREACH(ad->keylistroot, l, inc_key) { 190 /* avoid lots of dereferences */ 191 key = *inc_key; 192 if ((key.mask == 0 || evas_key_modifier_is_set(ev->modifiers, key.mask)) 193 && (key.modkey == wd->current_modkey 194 || (!key.modkey && !wd->current_modkey) 195 || key.modkey == '*' ) // wildcard 196 && !strcmp(key.key, ev->key) 197 && key.func) 198 if (key.func(&key.arg, wd)) { 199 wd->current_modkey = wd->count = 0; 200 gui_count_update(wd); 201 gui_modkey_update(wd); 202 return EINA_TRUE; 203 } 204 } 205 return EINA_FALSE; 206 } 207 208 static void 209 webview_keypress_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) 210 { 211 Arg a = { .i = ModeNormal, .s = NULL }; 212 // int keyval; 213 Evas_Event_Key_Down *ev = event_info; 214 Buffer_Data *td = data; 215 Window_Data *wd = td->window; 216 App_Data *ad = wd->app; 217 // GdkModifierType irrelevant; 218 219 /* Get a mask of modifiers that shouldn't be considered for this event. 220 * E.g.: It shouldn't matter whether ';' is shifted or not. */ 221 // gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode, 222 // event->state, event->group, &keyval, NULL, NULL, &irrelevant); 223 224 switch (wd->mode) { 225 case ModeNormal: 226 // if ((CLEAN(event->state) & ~irrelevant) == 0) { 227 if (IS_ESCAPE(ev)) { 228 a.i = Info; 229 a.s = strdup(""); 230 echo(&a, wd); 231 elm_box_clear(wd->event_box); 232 evas_object_hide(wd->event_box); 233 free(a.s); 234 } else if (wd->current_modkey == 0 && 235 (( strcmp(ev->key, "1") >= 0 && strcmp(ev->key, "9") <= 0) 236 || (!strcmp(ev->key, "0") && wd->count))) { 237 // ad->count = (ad->count ? ad->count * 10 : 0) + (ev->key - "0"); 238 wd->count = (wd->count ? wd->count * 10 : 0) + atoi(ev->key); 239 gui_count_update(wd); 240 return; 241 } else if (strchr(ad->modkeys, ev->key[0]) && wd->current_modkey != ev->key[0]) { 242 wd->current_modkey = ev->key[0]; 243 gui_modkey_update(wd); 244 return; 245 } 246 // } 247 /* keybindings */ 248 if (process_keypress(event_info, wd) == EINA_TRUE) return; 249 250 break; 251 case ModeInsert: 252 if (IS_ESCAPE(ev)) { 253 a.i = Silent; 254 a.s = strdup("hints.clearFocus();"); 255 script(&a, wd); 256 free(a.s); 257 a.i = ModeNormal; 258 set(&a, wd); 259 // ewk_view_input_method_state_set(td->web, FALSE); 260 return; 261 } 262 case ModePassThrough: 263 if (IS_ESCAPE(ev)) { 264 echo(&a, wd); 265 set(&a, wd); 266 return; 267 } 268 break; 269 case ModeSendKey: 270 echo(&a, wd); 271 set(&a, wd); 272 break; 273 } 274 } 275 276 /* 277 static void 278 console_cb(void *data, Evas_Object *obj, const char *message, unsigned int line, const char *source) 279 { 280 Arg a; 281 Buffer_Data *td = data; 282 283 // Don't change internal mode if the browser doesn't have focus to prevent inconsistent states 284 // if (gtk_window_has_toplevel_focus(window)) { 285 if (elm_object_focus_get(td->window->win)) { 286 if (!strcmp(message, "hintmode_off") || !strcmp(message, "insertmode_off")) { 287 a.i = ModeNormal; 288 set(&a, td->window); 289 return; 290 } else if (!strcmp(message, "insertmode_on")) { 291 a.i = ModeInsert; 292 set(&a, td->window); 293 return; 294 } 295 } 296 } 297 */ 298 299 void 300 icon_changed_cb(void *data, Evas_Object *obj, void *event_info) 301 { 302 Buffer_Data *bd = data; 303 Window_Data *wd = bd->window; 304 305 if (bd != wd->cur_buf) 306 return; 307 308 make_favicon(wd->status_favicon, bd); 309 } 310 311 static void 312 bf_list_changed_cb(void *data, Evas_Object *obj, void *event_info) 313 { 314 Buffer_Data *bd = data; 315 Window_Data *wd = bd->window; 316 317 make_bf_list(wd->status_back_forward, bd); 318 } 319 320 static void 321 policy_new_window_cb(void *data, Evas_Object *obj, void *event_info) 322 { 323 Buffer_Data *bd = data; 324 Ewk_Navigation_Policy_Decision *decision = event_info; 325 Ewk_Url_Request *req = ewk_navigation_policy_request_get(decision); 326 const char *url = ewk_url_request_url_get(req); 327 328 buffer_add(0, bd->window, url, NULL); 329 printf("policy_new_window()\n"); 330 } 331 332 static void 333 close_window_cb(void *data, Evas_Object *obj, void *event_info) 334 { 335 printf("close_window()\n"); 336 } 337 338 static void 339 create_window_cb(void *data, Evas_Object *obj, void *event_info) 340 { 341 printf("create_window()\n"); 342 } 343 344 static void 345 free_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) 346 { 347 Buffer_Data *bd = data; 348 Window_Data *wd = bd->window; 349 Session_Item *si; 350 351 if ((si = evas_object_data_get(wd->cur_buf->view, "session"))) 352 session_window_tabs_del(wd->session_window, si); 353 354 // if (!wd->app->exiting) 355 // wd->cur_buf->view = NULL; 356 357 wd->buffer_list = eina_list_remove(wd->buffer_list, bd); 358 359 printf("buffer_free_cb()\n"); 360 free(bd); 361 } 362 363 static void 364 mousewheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) 365 { 366 Buffer_Data *bd = data; 367 gui_scroll_update(bd->window); 368 } 369 370 Buffer_Data* 371 buffer_add(const unsigned char flags, Window_Data *wd, const char *url, Session_Item *session_item) 372 { 373 Buffer_Data *bd; 374 Ewk_Settings *settings; 375 376 bd = calloc(1, sizeof(Buffer_Data)); 377 if (!bd) 378 return NULL; 379 380 /* if the InNewWindow flag is set, create the buffer in a new window */ 381 if (flags & InNewWindow) 382 wd = window_add(wd->app, NULL); 383 384 wd->buf_total++; 385 386 bd->window = wd; 387 bd->buf_number = wd->buf_total; 388 bd->inspector_enabled = EINA_FALSE; 389 bd->zoom_level = DEFAULT_ZOOM_LEVEL; 390 391 #if 1 392 Ewk_View_Smart_Class *ewkViewClass = miniBrowserViewSmartClass(); 393 /* located in buffer_callback.c */ 394 ewkViewClass->run_javascript_alert = on_javascript_alert; 395 ewkViewClass->run_javascript_confirm = on_javascript_confirm; 396 ewkViewClass->run_javascript_prompt = on_javascript_prompt; 397 ewkViewClass->window_geometry_get = on_window_geometry_get; 398 ewkViewClass->window_geometry_set = on_window_geometry_set; 399 // ewkViewClass->fullscreen_enter = on_fullscreen_enter; 400 // ewkViewClass->fullscreen_exit = on_fullscreen_exit; 401 402 Evas *evas = evas_object_evas_get(wd->win); 403 Evas_Smart *smart = evas_smart_class_new(&ewkViewClass->sc); 404 bd->view = ewk_view_smart_add(evas, smart, ewk_context_default_get()); 405 // ewk_view_theme_set(bd->view, THEME_DIR "/default.edj"); 406 ewk_view_theme_set(bd->view, "/usr/share/ewebkit-0/themes/default.edj"); 407 #else 408 bd->view = ewk_view_add(evas_object_evas_get(wd->win)); 409 ewk_view_theme_set(bd->view, "/usr/share/ewebkit-0/themes/default.edj"); 410 #endif 411 412 settings = ewk_view_settings_get(bd->view); 413 ewk_settings_file_access_from_file_urls_allowed_set(settings, EINA_TRUE); 414 ewk_settings_dns_prefetching_enabled_set(settings, EINA_TRUE); 415 ewk_settings_developer_extras_enabled_set(settings, EINA_TRUE); 416 ewk_settings_frame_flattening_enabled_set(settings, EINA_TRUE); 417 ewk_settings_preferred_minimum_contents_width_set(settings, 0); 418 ewk_settings_continuous_spell_checking_enabled_set(EINA_TRUE); 419 420 evas_object_size_hint_weight_set(bd->view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 421 evas_object_size_hint_align_set(bd->view, EVAS_HINT_FILL, EVAS_HINT_FILL); 422 423 if (wd->cur_buf) 424 wd->buffer_list = eina_list_append_relative(wd->buffer_list, bd, wd->cur_buf); 425 else 426 wd->buffer_list = eina_list_append(wd->buffer_list, bd); 427 428 Evas_Object *v = bd->view; 429 430 // elm_web_window_create_hook_set(td->web, webview_create_window_cb, td->window); 431 // elm_web_console_message_hook_set(td->web, webview_console_cb, td); 432 433 /* misc callbacks - buffer_callback.c */ 434 evas_object_smart_callback_add(v, "webprocess,crashed", webprocess_crashed_cb, wd); 435 evas_object_smart_callback_add(v, "authentication,request", on_authentication_request, wd); 436 evas_object_smart_callback_add(v, "tooltip,text,set", on_tooltip_text_set, wd); 437 evas_object_smart_callback_add(v, "tooltip,text,unset", on_tooltip_text_unset, wd); 438 evas_object_smart_callback_add(v, "file,chooser,request", on_file_chooser_request, wd); 439 /* not yet implemented in ewebkit2 440 evas_object_smart_callback_add(v, "link,hover,in", hoverlink_cb, td); 441 evas_object_smart_callback_add(v, "link,hover,out",hoverlink_out_cb, td); 442 evas_object_smart_callback_add(v, "inputmethod,changed", inputmethod_changed_cb, td); 443 */ 444 445 /* downloads - download.h */ 446 evas_object_smart_callback_add(v, "download,request", download_request_cb, wd); 447 evas_object_smart_callback_add(v, "download,finished", download_finished_cb, wd); 448 evas_object_smart_callback_add(v, "download,failed", download_failed_cb, wd); 449 evas_object_smart_callback_add(v, "download,cancelled", download_cancelled_cb, wd); 450 451 /* navigation */ 452 evas_object_smart_callback_add(v, "title,changed", title_changed_cb, bd); 453 evas_object_smart_callback_add(v, "url,changed", url_changed_cb, bd); 454 evas_object_smart_callback_add(v, "load,progress", load_progress_cb, bd); 455 evas_object_smart_callback_add(v, "load,finished", load_finished_cb, bd); 456 evas_object_smart_callback_add(v, "load,error", load_error_cb, bd); 457 458 /* other */ 459 evas_object_smart_callback_add(v, "icon,changed", icon_changed_cb, bd); 460 evas_object_smart_callback_add(v, "back,forward,list,changed", bf_list_changed_cb, bd); 461 evas_object_smart_callback_add(v, "policy,decision,new,window", policy_new_window_cb, bd); 462 evas_object_smart_callback_add(v, "close,window", close_window_cb, bd); 463 evas_object_smart_callback_add(v, "create,window", create_window_cb, bd); 464 465 /* evas events */ 466 evas_object_event_callback_add(v, EVAS_CALLBACK_FREE, free_cb, bd); 467 evas_object_event_callback_add(v, EVAS_CALLBACK_KEY_DOWN, webview_keypress_cb, bd); 468 evas_object_event_callback_add(v, EVAS_CALLBACK_MOUSE_WHEEL, mousewheel_cb, bd); 469 470 if (url) 471 ewk_view_url_set(bd->view, url); 472 else 473 ewk_view_url_set(bd->view, config_home_page_get(wd->app->config)); 474 475 if (!session_item) { 476 if (!(session_item = session_item_new(ewk_view_url_get(bd->view), EINA_FALSE, 0, 0))) 477 CRITICAL("Could not create session object"); 478 session_window_tabs_add(wd->session_window, session_item); 479 } 480 481 evas_object_data_set(bd->view, "session", session_item); 482 evas_object_data_set(bd->view, "buffer_data", bd); 483 evas_object_hide(bd->view); 484 485 if (flags & SwitchToBuffer) 486 window_main_buffer_set(bd); 487 488 return bd; 489 } 490