2020-04-23 16:14:31 -03:00
/*
2021-02-16 15:53:47 -03:00
* Copyright ( c ) 2020 - 2021 , Andreas Kling < kling @ serenityos . org >
2021-04-26 06:52:19 -03:00
* Copyright ( c ) 2021 , Maciej Zygmanowski < sppmacd @ pm . me >
2021-09-03 07:14:37 -03:00
* Copyright ( c ) 2021 , Sam Atkins < atkinssj @ serenityos . org >
2020-04-23 16:14:31 -03:00
*
2021-04-22 05:24:48 -03:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-04-23 16:14:31 -03:00
*/
# include "Tab.h"
# include "BookmarksBarWidget.h"
2020-08-10 17:46:23 -03:00
# include "Browser.h"
2021-05-18 14:23:53 -03:00
# include "BrowserWindow.h"
2020-05-23 13:53:09 -03:00
# include "ConsoleWidget.h"
2020-05-05 18:58:22 -03:00
# include "DownloadWidget.h"
2021-06-07 18:21:16 -03:00
# include "InspectorWidget.h"
2020-05-07 06:57:53 -03:00
# include <AK/StringBuilder.h>
2021-05-25 09:06:03 -03:00
# include <AK/URL.h>
2020-12-20 07:47:44 -03:00
# include <Applications/Browser/TabGML.h>
2020-04-23 16:14:31 -03:00
# include <LibGUI/Action.h>
# include <LibGUI/Application.h>
# include <LibGUI/BoxLayout.h>
# include <LibGUI/Button.h>
2020-05-05 21:33:37 -03:00
# include <LibGUI/Clipboard.h>
2020-04-23 16:14:31 -03:00
# include <LibGUI/Menu.h>
2021-07-30 08:16:58 -03:00
# include <LibGUI/MessageBox.h>
2021-04-13 11:18:20 -03:00
# include <LibGUI/Statusbar.h>
2020-04-23 16:14:31 -03:00
# include <LibGUI/TextBox.h>
2021-04-13 11:18:20 -03:00
# include <LibGUI/Toolbar.h>
# include <LibGUI/ToolbarContainer.h>
2020-04-23 16:14:31 -03:00
# include <LibGUI/Window.h>
2020-05-23 13:53:09 -03:00
# include <LibJS/Interpreter.h>
2021-05-20 15:47:30 -03:00
# include <LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.h>
2020-11-22 11:53:01 -03:00
# include <LibWeb/Layout/BlockBox.h>
2021-09-08 06:27:46 -03:00
# include <LibWeb/Layout/InitialContainingBlock.h>
2020-06-01 15:42:50 -03:00
# include <LibWeb/Loader/ResourceLoader.h>
2020-08-17 11:20:47 -03:00
# include <LibWeb/OutOfProcessWebView.h>
2021-05-30 07:36:53 -03:00
# include <LibWeb/Page/BrowsingContext.h>
2020-04-23 16:14:31 -03:00
namespace Browser {
2020-06-12 16:29:27 -03:00
URL url_from_user_input ( const String & input )
{
2021-09-10 20:15:44 -03:00
if ( input . starts_with ( " ? " ) & & ! g_search_engine . is_null ( ) )
return URL ( g_search_engine . replace ( " {} " , URL : : percent_encode ( input . substring_view ( 1 ) ) ) ) ;
2021-04-26 06:52:19 -03:00
2020-06-12 16:29:27 -03:00
auto url = URL ( input ) ;
if ( url . is_valid ( ) )
return url ;
StringBuilder builder ;
builder . append ( " http:// " ) ;
builder . append ( input ) ;
return URL ( builder . build ( ) ) ;
}
2021-03-27 07:12:35 -03:00
void Tab : : start_download ( const URL & url )
2020-10-02 14:00:45 -03:00
{
2021-05-18 14:23:53 -03:00
auto window = GUI : : Window : : construct ( & this - > window ( ) ) ;
2021-05-31 13:19:13 -03:00
window - > resize ( 300 , 170 ) ;
2020-10-04 07:39:02 -03:00
window - > set_title ( String : : formatted ( " 0% of {} " , url . basename ( ) ) ) ;
2020-10-02 14:00:45 -03:00
window - > set_resizable ( false ) ;
window - > set_main_widget < DownloadWidget > ( url ) ;
window - > show ( ) ;
}
2021-03-27 07:12:35 -03:00
void Tab : : view_source ( const URL & url , const String & source )
2021-02-23 09:18:22 -03:00
{
2021-05-18 14:23:53 -03:00
auto window = GUI : : Window : : construct ( & this - > window ( ) ) ;
2021-02-23 09:18:22 -03:00
auto & editor = window - > set_main_widget < GUI : : TextEditor > ( ) ;
editor . set_text ( source ) ;
editor . set_mode ( GUI : : TextEditor : : ReadOnly ) ;
2021-05-20 15:47:30 -03:00
editor . set_syntax_highlighter ( make < Web : : HTML : : SyntaxHighlighter > ( ) ) ;
2021-02-23 09:18:22 -03:00
editor . set_ruler_visible ( true ) ;
window - > resize ( 640 , 480 ) ;
2021-03-27 07:12:35 -03:00
window - > set_title ( url . to_string ( ) ) ;
2021-07-21 13:02:15 -03:00
window - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/filetype-text.png " ) ) ;
2021-02-23 09:18:22 -03:00
window - > show ( ) ;
}
2021-08-24 11:35:46 -03:00
Tab : : Tab ( BrowserWindow & window )
2020-04-23 16:14:31 -03:00
{
2020-12-20 07:47:44 -03:00
load_from_gml ( tab_gml ) ;
2020-04-23 16:14:31 -03:00
2021-04-13 11:18:20 -03:00
m_toolbar_container = * find_descendant_of_type_named < GUI : : ToolbarContainer > ( " toolbar_container " ) ;
auto & toolbar = * find_descendant_of_type_named < GUI : : Toolbar > ( " toolbar " ) ;
2020-09-14 13:41:22 -03:00
2021-01-01 04:57:48 -03:00
auto & webview_container = * find_descendant_of_type_named < GUI : : Widget > ( " webview_container " ) ;
2020-07-06 16:46:37 -03:00
2021-08-24 11:35:46 -03:00
m_web_content_view = webview_container . add < Web : : OutOfProcessWebView > ( ) ;
2020-04-23 16:14:31 -03:00
2021-05-23 19:58:00 -03:00
auto & go_back_button = toolbar . add_action ( window . go_back_action ( ) ) ;
go_back_button . on_context_menu_request = [ this ] ( auto & context_menu_event ) {
if ( ! m_history . can_go_back ( ) )
return ;
int i = 0 ;
m_go_back_context_menu = GUI : : Menu : : construct ( ) ;
2021-05-26 15:19:35 -03:00
for ( auto & url : m_history . get_back_title_history ( ) ) {
2021-05-23 19:58:00 -03:00
i + + ;
m_go_back_context_menu - > add_action ( GUI : : Action : : create ( url . to_string ( ) ,
2021-07-21 13:02:15 -03:00
Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/filetype-html.png " ) ,
2021-05-23 19:58:00 -03:00
[ this , i ] ( auto & ) { go_back ( i ) ; } ) ) ;
}
m_go_back_context_menu - > popup ( context_menu_event . screen_position ( ) ) ;
} ;
auto & go_forward_button = toolbar . add_action ( window . go_forward_action ( ) ) ;
go_forward_button . on_context_menu_request = [ this ] ( auto & context_menu_event ) {
if ( ! m_history . can_go_forward ( ) )
return ;
int i = 0 ;
m_go_forward_context_menu = GUI : : Menu : : construct ( ) ;
2021-05-26 15:19:35 -03:00
for ( auto & url : m_history . get_forward_title_history ( ) ) {
2021-05-23 19:58:00 -03:00
i + + ;
m_go_forward_context_menu - > add_action ( GUI : : Action : : create ( url . to_string ( ) ,
2021-07-21 13:02:15 -03:00
Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/filetype-html.png " ) ,
2021-05-23 19:58:00 -03:00
[ this , i ] ( auto & ) { go_forward ( i ) ; } ) ) ;
}
m_go_forward_context_menu - > popup ( context_menu_event . screen_position ( ) ) ;
} ;
2021-05-18 14:23:53 -03:00
toolbar . add_action ( window . go_home_action ( ) ) ;
toolbar . add_action ( window . reload_action ( ) ) ;
2020-04-23 16:14:31 -03:00
2021-08-15 02:48:53 -03:00
m_location_box = toolbar . add < GUI : : UrlBox > ( ) ;
2020-09-20 16:43:44 -03:00
m_location_box - > set_placeholder ( " Address " ) ;
2020-04-23 16:14:31 -03:00
m_location_box - > on_return_pressed = [ this ] {
2021-07-30 08:16:58 -03:00
if ( m_location_box - > text ( ) . starts_with ( ' ? ' ) & & g_search_engine . is_empty ( ) ) {
GUI : : MessageBox : : show ( & this - > window ( ) , " Select a search engine in the Settings menu before searching. " , " No search engine selected " , GUI : : MessageBox : : Type : : Information ) ;
return ;
}
2020-06-12 16:29:27 -03:00
auto url = url_from_user_input ( m_location_box - > text ( ) ) ;
2020-07-06 16:46:37 -03:00
load ( url ) ;
2020-04-23 16:14:31 -03:00
} ;
2021-07-14 12:38:45 -03:00
m_location_box - > add_custom_context_menu_action ( GUI : : Action : : create ( " Paste && Go " , [ this ] ( auto & ) {
2021-07-25 06:59:30 -03:00
if ( ! GUI : : Clipboard : : the ( ) . mime_type ( ) . starts_with ( " text/ " ) )
return ;
auto const & paste_text = GUI : : Clipboard : : the ( ) . data ( ) ;
if ( paste_text . is_empty ( ) )
return ;
m_location_box - > set_text ( paste_text ) ;
2020-05-22 16:59:14 -03:00
m_location_box - > on_return_pressed ( ) ;
} ) ) ;
2020-04-23 16:14:31 -03:00
m_bookmark_button = toolbar . add < GUI : : Button > ( ) ;
2021-04-13 11:18:20 -03:00
m_bookmark_button - > set_button_style ( Gfx : : ButtonStyle : : Coolbar ) ;
2021-02-16 15:08:09 -03:00
m_bookmark_button - > set_focus_policy ( GUI : : FocusPolicy : : TabFocus ) ;
2021-07-21 13:02:15 -03:00
m_bookmark_button - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/bookmark-contour.png " ) ) ;
2020-12-29 21:23:32 -03:00
m_bookmark_button - > set_fixed_size ( 22 , 22 ) ;
2020-04-23 16:14:31 -03:00
2020-05-12 15:30:33 -03:00
m_bookmark_button - > on_click = [ this ] ( auto ) {
2021-08-15 02:52:27 -03:00
bookmark_current_url ( ) ;
2020-04-23 16:14:31 -03:00
} ;
2021-08-15 02:52:27 -03:00
auto bookmark_action = GUI : : Action : : create (
" Bookmark current URL " , { Mod_Ctrl , Key_D } , [ this ] ( auto & ) {
bookmark_current_url ( ) ;
} ,
this ) ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_load_start = [ this ] ( auto & url ) {
2020-06-30 16:11:35 -03:00
m_location_box - > set_icon ( nullptr ) ;
2020-04-23 16:14:31 -03:00
m_location_box - > set_text ( url . to_string ( ) ) ;
2020-08-19 00:34:28 -03:00
// don't add to history if back or forward is pressed
if ( ! m_is_history_navigation )
2021-05-26 15:19:35 -03:00
m_history . push ( url , title ( ) ) ;
2020-08-19 00:34:28 -03:00
m_is_history_navigation = false ;
2020-04-23 16:14:31 -03:00
update_actions ( ) ;
update_bookmark_button ( url . to_string ( ) ) ;
2021-09-01 08:50:47 -03:00
if ( m_dom_inspector_widget )
m_dom_inspector_widget - > clear_dom_json ( ) ;
2021-09-01 13:21:48 -03:00
if ( m_console_widget )
2021-09-04 08:12:12 -03:00
m_console_widget - > reset ( ) ;
2021-09-01 08:50:47 -03:00
} ;
hooks ( ) . on_load_finish = [ this ] ( auto & ) {
if ( m_dom_inspector_widget )
m_web_content_view - > inspect_dom_tree ( ) ;
2020-04-23 16:14:31 -03:00
} ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_link_click = [ this ] ( auto & url , auto & target , unsigned modifiers ) {
2020-05-22 22:35:09 -03:00
if ( target = = " _blank " | | modifiers = = Mod_Ctrl ) {
on_tab_open_request ( url ) ;
} else {
2020-07-06 16:46:37 -03:00
load ( url ) ;
2020-04-23 16:14:31 -03:00
}
} ;
2020-05-05 17:42:50 -03:00
m_link_context_menu = GUI : : Menu : : construct ( ) ;
2021-04-09 15:49:25 -03:00
auto link_default_action = GUI : : Action : : create ( " &Open " , [ this ] ( auto & ) {
2020-07-06 16:46:37 -03:00
hooks ( ) . on_link_click ( m_link_context_menu_url , " " , 0 ) ;
2020-08-29 05:56:42 -03:00
} ) ;
2020-10-02 14:00:45 -03:00
m_link_context_menu - > add_action ( link_default_action ) ;
m_link_context_menu_default_action = link_default_action ;
2021-04-09 15:49:25 -03:00
m_link_context_menu - > add_action ( GUI : : Action : : create ( " Open in New &Tab " , [ this ] ( auto & ) {
2020-07-06 16:46:37 -03:00
hooks ( ) . on_link_click ( m_link_context_menu_url , " _blank " , 0 ) ;
2020-05-05 17:42:50 -03:00
} ) ) ;
2020-10-02 14:00:45 -03:00
m_link_context_menu - > add_separator ( ) ;
2021-04-09 15:49:25 -03:00
m_link_context_menu - > add_action ( GUI : : Action : : create ( " &Copy URL " , [ this ] ( auto & ) {
2020-09-05 11:16:01 -03:00
GUI : : Clipboard : : the ( ) . set_plain_text ( m_link_context_menu_url . to_string ( ) ) ;
2020-05-05 21:33:37 -03:00
} ) ) ;
2020-05-05 18:58:22 -03:00
m_link_context_menu - > add_separator ( ) ;
2021-04-09 15:49:25 -03:00
m_link_context_menu - > add_action ( GUI : : Action : : create ( " &Download " , [ this ] ( auto & ) {
2020-10-02 14:00:45 -03:00
start_download ( m_link_context_menu_url ) ;
2020-05-05 18:58:22 -03:00
} ) ) ;
2021-08-17 13:00:27 -03:00
m_link_context_menu - > add_separator ( ) ;
m_link_context_menu - > add_action ( window . inspect_dom_node_action ( ) ) ;
2020-05-05 17:42:50 -03:00
2020-07-06 16:46:37 -03:00
hooks ( ) . on_link_context_menu_request = [ this ] ( auto & url , auto & screen_position ) {
2020-07-06 15:00:56 -03:00
m_link_context_menu_url = url ;
2020-08-29 05:56:42 -03:00
m_link_context_menu - > popup ( screen_position , m_link_context_menu_default_action ) ;
2020-05-05 17:42:50 -03:00
} ;
2020-10-02 14:03:10 -03:00
m_image_context_menu = GUI : : Menu : : construct ( ) ;
2021-04-09 15:49:25 -03:00
m_image_context_menu - > add_action ( GUI : : Action : : create ( " &Open Image " , [ this ] ( auto & ) {
2020-10-02 14:03:10 -03:00
hooks ( ) . on_link_click ( m_image_context_menu_url , " " , 0 ) ;
} ) ) ;
2021-04-09 15:49:25 -03:00
m_image_context_menu - > add_action ( GUI : : Action : : create ( " Open Image in New &Tab " , [ this ] ( auto & ) {
2020-10-02 14:03:10 -03:00
hooks ( ) . on_link_click ( m_image_context_menu_url , " _blank " , 0 ) ;
} ) ) ;
m_image_context_menu - > add_separator ( ) ;
2021-04-09 15:49:25 -03:00
m_image_context_menu - > add_action ( GUI : : Action : : create ( " &Copy Image " , [ this ] ( auto & ) {
2020-10-02 14:03:10 -03:00
if ( m_image_context_menu_bitmap . is_valid ( ) )
GUI : : Clipboard : : the ( ) . set_bitmap ( * m_image_context_menu_bitmap . bitmap ( ) ) ;
} ) ) ;
2021-04-09 15:49:25 -03:00
m_image_context_menu - > add_action ( GUI : : Action : : create ( " Copy Image &URL " , [ this ] ( auto & ) {
2020-10-02 14:03:10 -03:00
GUI : : Clipboard : : the ( ) . set_plain_text ( m_image_context_menu_url . to_string ( ) ) ;
} ) ) ;
m_image_context_menu - > add_separator ( ) ;
2021-04-09 15:49:25 -03:00
m_image_context_menu - > add_action ( GUI : : Action : : create ( " &Download " , [ this ] ( auto & ) {
2020-10-02 14:03:10 -03:00
start_download ( m_image_context_menu_url ) ;
} ) ) ;
2021-08-17 13:00:27 -03:00
m_image_context_menu - > add_separator ( ) ;
m_image_context_menu - > add_action ( window . inspect_dom_node_action ( ) ) ;
2020-10-02 14:03:10 -03:00
hooks ( ) . on_image_context_menu_request = [ this ] ( auto & image_url , auto & screen_position , const Gfx : : ShareableBitmap & shareable_bitmap ) {
m_image_context_menu_url = image_url ;
m_image_context_menu_bitmap = shareable_bitmap ;
m_image_context_menu - > popup ( screen_position ) ;
} ;
2020-07-06 16:18:16 -03:00
hooks ( ) . on_link_middle_click = [ this ] ( auto & href , auto & , auto ) {
hooks ( ) . on_link_click ( href , " _blank " , 0 ) ;
2020-05-06 16:34:10 -03:00
} ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_title_change = [ this ] ( auto & title ) {
2020-04-23 16:14:31 -03:00
if ( title . is_null ( ) ) {
2021-05-26 15:19:35 -03:00
m_history . update_title ( url ( ) . to_string ( ) ) ;
2020-07-06 16:46:37 -03:00
m_title = url ( ) . to_string ( ) ;
2020-04-23 16:14:31 -03:00
} else {
2021-05-26 15:19:35 -03:00
m_history . update_title ( title ) ;
2020-04-23 16:14:31 -03:00
m_title = title ;
}
if ( on_title_change )
on_title_change ( m_title ) ;
} ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_favicon_change = [ this ] ( auto & icon ) {
2020-04-24 17:47:53 -03:00
m_icon = icon ;
2020-06-29 15:35:53 -03:00
m_location_box - > set_icon ( & icon ) ;
2020-04-24 17:28:05 -03:00
if ( on_favicon_change )
2020-04-24 17:47:53 -03:00
on_favicon_change ( icon ) ;
2020-04-24 17:28:05 -03:00
} ;
2021-04-13 18:30:41 -03:00
hooks ( ) . on_get_cookie = [ this ] ( auto & url , auto source ) - > String {
2021-04-11 11:53:15 -03:00
if ( on_get_cookie )
2021-04-13 18:30:41 -03:00
return on_get_cookie ( url , source ) ;
2021-04-11 11:53:15 -03:00
return { } ;
} ;
2021-04-13 18:30:41 -03:00
hooks ( ) . on_set_cookie = [ this ] ( auto & url , auto & cookie , auto source ) {
2021-04-11 11:53:15 -03:00
if ( on_set_cookie )
2021-04-13 18:30:41 -03:00
on_set_cookie ( url , cookie , source ) ;
2021-04-11 11:53:15 -03:00
} ;
2021-02-23 09:18:22 -03:00
hooks ( ) . on_get_source = [ this ] ( auto & url , auto & source ) {
2021-03-27 07:12:35 -03:00
view_source ( url , source ) ;
2021-02-23 09:18:22 -03:00
} ;
2021-06-07 18:21:16 -03:00
hooks ( ) . on_get_dom_tree = [ this ] ( auto & dom_tree ) {
2021-08-23 12:16:08 -03:00
if ( m_dom_inspector_widget )
m_dom_inspector_widget - > set_dom_json ( dom_tree ) ;
2021-06-07 18:21:16 -03:00
} ;
2021-08-27 08:47:30 -03:00
hooks ( ) . on_get_dom_node_properties = [ this ] ( auto node_id , auto & specified , auto & computed ) {
m_dom_inspector_widget - > set_dom_node_properties_json ( node_id , specified , computed ) ;
} ;
2021-09-04 08:12:12 -03:00
hooks ( ) . on_js_console_new_message = [ this ] ( auto message_index ) {
2021-09-01 13:03:18 -03:00
if ( m_console_widget )
2021-09-04 08:12:12 -03:00
m_console_widget - > notify_about_new_console_message ( message_index ) ;
} ;
hooks ( ) . on_get_js_console_messages = [ this ] ( auto start_index , auto & message_types , auto & messages ) {
if ( m_console_widget )
m_console_widget - > handle_console_messages ( start_index , message_types , messages ) ;
2021-02-28 00:53:20 -03:00
} ;
2020-05-05 18:58:22 -03:00
auto focus_location_box_action = GUI : : Action : : create (
2021-06-24 12:41:16 -03:00
" Focus location box " , { Mod_Ctrl , Key_L } , Key_F6 , [ this ] ( auto & ) {
2020-05-05 18:58:22 -03:00
m_location_box - > set_focus ( true ) ;
2021-08-15 02:48:53 -03:00
m_location_box - > select_current_line ( ) ;
2020-05-05 18:58:22 -03:00
} ,
this ) ;
2020-04-23 16:14:31 -03:00
2021-04-13 11:18:20 -03:00
m_statusbar = * find_descendant_of_type_named < GUI : : Statusbar > ( " statusbar " ) ;
2020-04-23 16:14:31 -03:00
2020-07-06 16:46:37 -03:00
hooks ( ) . on_link_hover = [ this ] ( auto & url ) {
2020-07-05 12:02:44 -03:00
if ( url . is_valid ( ) )
m_statusbar - > set_text ( url . to_string ( ) ) ;
else
m_statusbar - > set_text ( " " ) ;
2020-04-23 16:14:31 -03:00
} ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_url_drop = [ this ] ( auto & url ) {
load ( url ) ;
2020-05-10 16:04:37 -03:00
} ;
2020-05-18 19:37:12 -03:00
m_tab_context_menu = GUI : : Menu : : construct ( ) ;
2021-04-09 12:07:34 -03:00
m_tab_context_menu - > add_action ( GUI : : Action : : create ( " &Reload Tab " , [ this ] ( auto & ) {
2021-05-18 14:23:53 -03:00
this - > window ( ) . reload_action ( ) . activate ( ) ;
2020-05-18 19:37:12 -03:00
} ) ) ;
2021-04-09 12:07:34 -03:00
m_tab_context_menu - > add_action ( GUI : : Action : : create ( " &Close Tab " , [ this ] ( auto & ) {
2020-05-18 19:37:12 -03:00
on_tab_close_request ( * this ) ;
} ) ) ;
2021-08-06 13:21:14 -03:00
m_tab_context_menu - > add_action ( GUI : : Action : : create ( " &Duplicate Tab " , [ this ] ( auto & ) {
on_tab_open_request ( url ( ) ) ;
} ) ) ;
m_tab_context_menu - > add_action ( GUI : : Action : : create ( " Close &Other Tabs " , [ this ] ( auto & ) {
on_tab_close_other_request ( * this ) ;
} ) ) ;
2020-06-27 17:23:21 -03:00
m_page_context_menu = GUI : : Menu : : construct ( ) ;
2021-05-18 14:23:53 -03:00
m_page_context_menu - > add_action ( window . go_back_action ( ) ) ;
m_page_context_menu - > add_action ( window . go_forward_action ( ) ) ;
m_page_context_menu - > add_action ( window . reload_action ( ) ) ;
2020-06-27 17:23:21 -03:00
m_page_context_menu - > add_separator ( ) ;
2021-07-14 09:33:35 -03:00
m_page_context_menu - > add_action ( window . copy_selection_action ( ) ) ;
2021-07-14 09:55:36 -03:00
m_page_context_menu - > add_action ( window . select_all_action ( ) ) ;
2021-07-14 09:33:35 -03:00
m_page_context_menu - > add_separator ( ) ;
2021-05-18 14:23:53 -03:00
m_page_context_menu - > add_action ( window . view_source_action ( ) ) ;
m_page_context_menu - > add_action ( window . inspect_dom_tree_action ( ) ) ;
2021-08-17 13:00:27 -03:00
m_page_context_menu - > add_action ( window . inspect_dom_node_action ( ) ) ;
2020-07-06 16:46:37 -03:00
hooks ( ) . on_context_menu_request = [ & ] ( auto & screen_position ) {
2020-06-27 17:23:21 -03:00
m_page_context_menu - > popup ( screen_position ) ;
} ;
2020-04-23 16:14:31 -03:00
}
Tab : : ~ Tab ( )
{
}
2020-07-07 10:04:05 -03:00
void Tab : : load ( const URL & url , LoadType load_type )
2020-04-23 16:14:31 -03:00
{
2020-08-19 00:34:28 -03:00
m_is_history_navigation = ( load_type = = LoadType : : HistoryNavigation ) ;
2021-08-24 11:35:46 -03:00
m_web_content_view - > load ( url ) ;
2021-08-15 02:48:53 -03:00
m_location_box - > set_focus ( false ) ;
2020-07-06 16:46:37 -03:00
}
URL Tab : : url ( ) const
{
return m_web_content_view - > url ( ) ;
}
void Tab : : reload ( )
{
load ( url ( ) ) ;
2020-04-23 16:14:31 -03:00
}
2021-05-23 19:58:00 -03:00
void Tab : : go_back ( int steps )
2020-07-07 10:04:05 -03:00
{
2021-05-23 19:58:00 -03:00
m_history . go_back ( steps ) ;
2020-07-07 10:04:05 -03:00
update_actions ( ) ;
2021-05-26 15:19:35 -03:00
load ( m_history . current ( ) . url , LoadType : : HistoryNavigation ) ;
2020-07-07 10:04:05 -03:00
}
2021-05-23 19:58:00 -03:00
void Tab : : go_forward ( int steps )
2020-07-07 10:04:05 -03:00
{
2021-05-23 19:58:00 -03:00
m_history . go_forward ( steps ) ;
2020-07-07 10:04:05 -03:00
update_actions ( ) ;
2021-05-26 15:19:35 -03:00
load ( m_history . current ( ) . url , LoadType : : HistoryNavigation ) ;
2020-07-07 10:04:05 -03:00
}
2020-04-23 16:14:31 -03:00
void Tab : : update_actions ( )
{
2021-05-18 14:23:53 -03:00
auto & window = this - > window ( ) ;
if ( this ! = & window . active_tab ( ) )
return ;
window . go_back_action ( ) . set_enabled ( m_history . can_go_back ( ) ) ;
window . go_forward_action ( ) . set_enabled ( m_history . can_go_forward ( ) ) ;
2020-04-23 16:14:31 -03:00
}
2021-08-15 02:52:27 -03:00
void Tab : : bookmark_current_url ( )
{
auto url = this - > url ( ) . to_string ( ) ;
if ( BookmarksBarWidget : : the ( ) . contains_bookmark ( url ) ) {
BookmarksBarWidget : : the ( ) . remove_bookmark ( url ) ;
} else {
BookmarksBarWidget : : the ( ) . add_bookmark ( url , m_title ) ;
}
update_bookmark_button ( url ) ;
}
2020-04-23 16:14:31 -03:00
void Tab : : update_bookmark_button ( const String & url )
{
2020-04-25 12:20:23 -03:00
if ( BookmarksBarWidget : : the ( ) . contains_bookmark ( url ) ) {
2021-07-21 13:02:15 -03:00
m_bookmark_button - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/bookmark-filled.png " ) ) ;
2020-04-30 00:41:48 -03:00
m_bookmark_button - > set_tooltip ( " Remove Bookmark " ) ;
2020-04-23 16:14:31 -03:00
} else {
2021-07-21 13:02:15 -03:00
m_bookmark_button - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/bookmark-contour.png " ) ) ;
2020-04-30 00:41:48 -03:00
m_bookmark_button - > set_tooltip ( " Add Bookmark " ) ;
2020-04-23 16:14:31 -03:00
}
}
void Tab : : did_become_active ( )
{
2020-05-18 22:31:12 -03:00
BookmarksBarWidget : : the ( ) . on_bookmark_click = [ this ] ( auto & url , unsigned modifiers ) {
2020-05-12 15:35:45 -03:00
if ( modifiers & Mod_Ctrl )
on_tab_open_request ( url ) ;
else
2020-07-06 16:46:37 -03:00
load ( url ) ;
2020-04-25 12:20:23 -03:00
} ;
BookmarksBarWidget : : the ( ) . on_bookmark_hover = [ this ] ( auto & , auto & url ) {
m_statusbar - > set_text ( url ) ;
} ;
BookmarksBarWidget : : the ( ) . remove_from_parent ( ) ;
m_toolbar_container - > add_child ( BookmarksBarWidget : : the ( ) ) ;
2021-05-18 14:23:53 -03:00
auto is_fullscreen = window ( ) . is_fullscreen ( ) ;
2020-05-19 12:11:01 -03:00
m_toolbar_container - > set_visible ( ! is_fullscreen ) ;
m_statusbar - > set_visible ( ! is_fullscreen ) ;
2021-05-18 14:23:53 -03:00
update_actions ( ) ;
2020-04-23 16:14:31 -03:00
}
2020-06-10 05:57:59 -03:00
void Tab : : context_menu_requested ( const Gfx : : IntPoint & screen_position )
2020-05-18 19:37:12 -03:00
{
m_tab_context_menu - > popup ( screen_position ) ;
}
2021-05-03 15:31:58 -03:00
GUI : : AbstractScrollableWidget & Tab : : view ( )
2020-07-06 16:46:37 -03:00
{
return * m_web_content_view ;
}
Web : : WebViewHooks & Tab : : hooks ( )
{
2020-07-07 10:04:05 -03:00
return * m_web_content_view ;
}
2020-10-04 07:39:02 -03:00
2021-04-17 17:08:06 -03:00
void Tab : : action_entered ( GUI : : Action & action )
{
2021-04-17 19:43:04 -03:00
m_statusbar - > set_override_text ( action . status_tip ( ) ) ;
2021-04-17 17:08:06 -03:00
}
2021-04-17 19:43:04 -03:00
void Tab : : action_left ( GUI : : Action & )
2021-04-17 17:08:06 -03:00
{
2021-04-17 19:43:04 -03:00
m_statusbar - > set_override_text ( { } ) ;
2021-04-17 17:08:06 -03:00
}
2021-05-18 14:23:53 -03:00
BrowserWindow const & Tab : : window ( ) const
{
return static_cast < BrowserWindow const & > ( * Widget : : window ( ) ) ;
}
BrowserWindow & Tab : : window ( )
{
return static_cast < BrowserWindow & > ( * Widget : : window ( ) ) ;
}
2021-08-27 13:40:25 -03:00
void Tab : : show_inspector_window ( Browser : : Tab : : InspectorTarget inspector_target )
2021-08-17 13:00:27 -03:00
{
2021-08-23 12:16:08 -03:00
if ( ! m_dom_inspector_widget ) {
auto window = GUI : : Window : : construct ( & this - > window ( ) ) ;
window - > resize ( 300 , 500 ) ;
2021-09-13 15:24:59 -03:00
window - > set_title ( " Inspector " ) ;
2021-08-23 12:16:08 -03:00
window - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/inspector-object.png " ) ) ;
window - > on_close = [ & ] ( ) {
2021-09-02 08:05:32 -03:00
m_web_content_view - > clear_inspected_dom_node ( ) ;
2021-08-23 12:16:08 -03:00
} ;
m_dom_inspector_widget = window - > set_main_widget < InspectorWidget > ( ) ;
2021-09-02 08:05:32 -03:00
m_dom_inspector_widget - > set_web_view ( * m_web_content_view ) ;
2021-09-01 08:50:47 -03:00
m_web_content_view - > inspect_dom_tree ( ) ;
2021-08-23 12:16:08 -03:00
}
2021-08-27 13:40:25 -03:00
if ( inspector_target = = InspectorTarget : : HoveredElement ) {
Optional < i32 > hovered_node = m_web_content_view - > get_hovered_node_id ( ) ;
VERIFY ( hovered_node . has_value ( ) ) ;
m_dom_inspector_widget - > set_inspected_node ( hovered_node . value ( ) ) ;
2021-08-27 16:21:30 -03:00
} else {
VERIFY ( inspector_target = = InspectorTarget : : Document ) ;
m_dom_inspector_widget - > select_default_node ( ) ;
2021-08-27 13:40:25 -03:00
}
2021-08-23 12:16:08 -03:00
auto * window = m_dom_inspector_widget - > window ( ) ;
window - > show ( ) ;
window - > move_to_front ( ) ;
2021-08-17 13:00:27 -03:00
}
2021-09-01 13:03:18 -03:00
void Tab : : show_console_window ( )
{
if ( ! m_console_widget ) {
auto console_window = GUI : : Window : : construct ( & window ( ) ) ;
console_window - > resize ( 500 , 300 ) ;
console_window - > set_title ( " JS Console " ) ;
console_window - > set_icon ( Gfx : : Bitmap : : try_load_from_file ( " /res/icons/16x16/filetype-javascript.png " ) ) ;
m_console_widget = console_window - > set_main_widget < ConsoleWidget > ( ) ;
m_console_widget - > on_js_input = [ this ] ( String const & js_source ) {
m_web_content_view - > js_console_input ( js_source ) ;
} ;
2021-09-04 08:12:12 -03:00
m_console_widget - > on_request_messages = [ this ] ( i32 start_index ) {
m_web_content_view - > js_console_request_messages ( start_index ) ;
} ;
2021-09-01 13:03:18 -03:00
}
auto * window = m_console_widget - > window ( ) ;
window - > show ( ) ;
window - > move_to_front ( ) ;
}
2020-04-23 16:14:31 -03:00
}