2023-01-12 19:27:17 +00:00
/*
* Copyright ( c ) 2023 , Linus Groh < linusg @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2023-01-12 20:22:14 +00:00
# include <AK/Error.h>
# include <AK/String.h>
2023-01-12 19:27:17 +00:00
# include <LibWebView/ViewImplementation.h>
namespace WebView {
WebContentClient & ViewImplementation : : client ( )
{
VERIFY ( m_client_state . client ) ;
return * m_client_state . client ;
}
WebContentClient const & ViewImplementation : : client ( ) const
{
VERIFY ( m_client_state . client ) ;
return * m_client_state . client ;
}
2023-01-12 20:30:06 +00:00
void ViewImplementation : : load ( AK : : URL const & url )
{
m_url = url ;
client ( ) . async_load_url ( url ) ;
}
void ViewImplementation : : load_html ( StringView html , AK : : URL const & url )
{
m_url = url ;
client ( ) . async_load_html ( html , url ) ;
}
void ViewImplementation : : load_empty_document ( )
{
load_html ( " " sv , { } ) ;
}
2023-01-12 19:49:49 +00:00
void ViewImplementation : : zoom_in ( )
{
if ( m_zoom_level > = ZOOM_MAX_LEVEL )
return ;
m_zoom_level + = ZOOM_STEP ;
update_zoom ( ) ;
}
void ViewImplementation : : zoom_out ( )
{
if ( m_zoom_level < = ZOOM_MIN_LEVEL )
return ;
m_zoom_level - = ZOOM_STEP ;
update_zoom ( ) ;
}
void ViewImplementation : : reset_zoom ( )
{
m_zoom_level = 1.0f ;
update_zoom ( ) ;
}
2023-01-12 20:44:42 +00:00
void ViewImplementation : : set_preferred_color_scheme ( Web : : CSS : : PreferredColorScheme color_scheme )
{
client ( ) . async_set_preferred_color_scheme ( color_scheme ) ;
}
2023-01-12 20:42:42 +00:00
DeprecatedString ViewImplementation : : selected_text ( )
{
return client ( ) . get_selected_text ( ) ;
}
void ViewImplementation : : select_all ( )
{
client ( ) . async_select_all ( ) ;
}
2023-01-12 19:58:00 +00:00
void ViewImplementation : : get_source ( )
{
client ( ) . async_get_source ( ) ;
}
2023-01-12 20:22:14 +00:00
void ViewImplementation : : inspect_dom_tree ( )
{
client ( ) . async_inspect_dom_tree ( ) ;
}
void ViewImplementation : : inspect_accessibility_tree ( )
{
client ( ) . async_inspect_accessibility_tree ( ) ;
}
ErrorOr < ViewImplementation : : DOMNodeProperties > ViewImplementation : : inspect_dom_node ( i32 node_id , Optional < Web : : CSS : : Selector : : PseudoElement > pseudo_element )
{
auto response = client ( ) . inspect_dom_node ( node_id , pseudo_element ) ;
if ( ! response . has_style ( ) )
return Error : : from_string_view ( " Inspected node returned no style " sv ) ;
return DOMNodeProperties {
. computed_style_json = TRY ( String : : from_deprecated_string ( response . take_computed_style ( ) ) ) ,
. resolved_style_json = TRY ( String : : from_deprecated_string ( response . take_resolved_style ( ) ) ) ,
. custom_properties_json = TRY ( String : : from_deprecated_string ( response . take_custom_properties ( ) ) ) ,
. node_box_sizing_json = TRY ( String : : from_deprecated_string ( response . take_node_box_sizing ( ) ) ) ,
} ;
}
void ViewImplementation : : clear_inspected_dom_node ( )
{
client ( ) . inspect_dom_node ( 0 , { } ) ;
}
i32 ViewImplementation : : get_hovered_node_id ( )
{
return client ( ) . get_hovered_node_id ( ) ;
}
2023-01-12 20:34:08 +00:00
void ViewImplementation : : debug_request ( DeprecatedString const & request , DeprecatedString const & argument )
{
client ( ) . async_debug_request ( request , argument ) ;
}
2023-01-12 20:39:08 +00:00
void ViewImplementation : : run_javascript ( StringView js_source )
{
client ( ) . async_run_javascript ( js_source ) ;
}
2023-03-12 12:35:06 -04:00
# if !defined(AK_OS_SERENITY)
2023-05-06 12:46:14 +02:00
ErrorOr < NonnullRefPtr < WebView : : WebContentClient > > ViewImplementation : : launch_web_content_process ( ReadonlySpan < String > candidate_web_content_paths , EnableCallgrindProfiling enable_callgrind_profiling , IsLayoutTestMode is_layout_test_mode )
2023-03-12 12:35:06 -04:00
{
int socket_fds [ 2 ] { } ;
TRY ( Core : : System : : socketpair ( AF_LOCAL , SOCK_STREAM , 0 , socket_fds ) ) ;
int ui_fd = socket_fds [ 0 ] ;
int wc_fd = socket_fds [ 1 ] ;
int fd_passing_socket_fds [ 2 ] { } ;
TRY ( Core : : System : : socketpair ( AF_LOCAL , SOCK_STREAM , 0 , fd_passing_socket_fds ) ) ;
int ui_fd_passing_fd = fd_passing_socket_fds [ 0 ] ;
int wc_fd_passing_fd = fd_passing_socket_fds [ 1 ] ;
if ( auto child_pid = TRY ( Core : : System : : fork ( ) ) ; child_pid = = 0 ) {
TRY ( Core : : System : : close ( ui_fd_passing_fd ) ) ;
TRY ( Core : : System : : close ( ui_fd ) ) ;
auto takeover_string = TRY ( String : : formatted ( " WebContent:{} " , wc_fd ) ) ;
TRY ( Core : : System : : setenv ( " SOCKET_TAKEOVER " sv , takeover_string , true ) ) ;
auto webcontent_fd_passing_socket_string = TRY ( String : : number ( wc_fd_passing_fd ) ) ;
ErrorOr < void > result ;
for ( auto const & path : candidate_web_content_paths ) {
2023-04-15 01:04:28 +01:00
constexpr auto callgrind_prefix_length = 3 ;
2023-05-08 13:17:16 +02:00
auto arguments = Vector {
2023-04-15 01:04:28 +01:00
" valgrind " sv ,
" --tool=callgrind " sv ,
" --instr-atstart=no " sv ,
path . bytes_as_string_view ( ) ,
" --webcontent-fd-passing-socket " sv ,
webcontent_fd_passing_socket_string
} ;
if ( enable_callgrind_profiling = = EnableCallgrindProfiling : : No )
2023-05-08 13:17:16 +02:00
arguments . remove ( 0 , callgrind_prefix_length ) ;
2023-05-06 12:46:14 +02:00
if ( is_layout_test_mode = = IsLayoutTestMode : : Yes )
arguments . append ( " --layout-test-mode " sv ) ;
2023-04-15 01:04:28 +01:00
2023-05-08 13:17:16 +02:00
result = Core : : System : : exec ( arguments [ 0 ] , arguments . span ( ) , Core : : System : : SearchInPath : : Yes ) ;
2023-03-12 12:35:06 -04:00
if ( ! result . is_error ( ) )
break ;
}
if ( result . is_error ( ) )
warnln ( " Could not launch any of {}: {} " , candidate_web_content_paths , result . error ( ) ) ;
VERIFY_NOT_REACHED ( ) ;
}
TRY ( Core : : System : : close ( wc_fd_passing_fd ) ) ;
TRY ( Core : : System : : close ( wc_fd ) ) ;
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( ui_fd ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
auto new_client = TRY ( adopt_nonnull_ref_or_enomem ( new ( nothrow ) WebView : : WebContentClient ( move ( socket ) , * this ) ) ) ;
new_client - > set_fd_passing_socket ( TRY ( Core : : LocalSocket : : adopt_fd ( ui_fd_passing_fd ) ) ) ;
2023-04-15 01:04:28 +01:00
if ( enable_callgrind_profiling = = EnableCallgrindProfiling : : Yes ) {
dbgln ( ) ;
dbgln ( " \033 [1;45mLaunched WebContent process under callgrind! \033 [0m " ) ;
dbgln ( " \033 [100mRun ` \033 [4mcallgrind_control -i on \033 [24m` to start instrumentation and ` \033 [4mcallgrind_control -i off \033 [24m` stop it again. \033 [0m " ) ;
dbgln ( ) ;
}
2023-03-12 12:35:06 -04:00
return new_client ;
}
# endif
2023-01-12 19:27:17 +00:00
}